sqlspec 0.26.0__py3-none-any.whl → 0.27.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sqlspec might be problematic. Click here for more details.
- sqlspec/__init__.py +7 -15
- sqlspec/_serialization.py +55 -25
- sqlspec/_typing.py +62 -52
- sqlspec/adapters/adbc/_types.py +1 -1
- sqlspec/adapters/adbc/adk/__init__.py +5 -0
- sqlspec/adapters/adbc/adk/store.py +870 -0
- sqlspec/adapters/adbc/config.py +62 -12
- sqlspec/adapters/adbc/data_dictionary.py +52 -2
- sqlspec/adapters/adbc/driver.py +144 -45
- sqlspec/adapters/adbc/litestar/__init__.py +5 -0
- sqlspec/adapters/adbc/litestar/store.py +504 -0
- sqlspec/adapters/adbc/type_converter.py +44 -50
- sqlspec/adapters/aiosqlite/_types.py +1 -1
- sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/adk/store.py +527 -0
- sqlspec/adapters/aiosqlite/config.py +86 -16
- sqlspec/adapters/aiosqlite/data_dictionary.py +34 -2
- sqlspec/adapters/aiosqlite/driver.py +127 -38
- sqlspec/adapters/aiosqlite/litestar/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/litestar/store.py +281 -0
- sqlspec/adapters/aiosqlite/pool.py +7 -7
- sqlspec/adapters/asyncmy/__init__.py +7 -1
- sqlspec/adapters/asyncmy/_types.py +1 -1
- sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
- sqlspec/adapters/asyncmy/adk/store.py +493 -0
- sqlspec/adapters/asyncmy/config.py +59 -17
- sqlspec/adapters/asyncmy/data_dictionary.py +41 -2
- sqlspec/adapters/asyncmy/driver.py +293 -62
- sqlspec/adapters/asyncmy/litestar/__init__.py +5 -0
- sqlspec/adapters/asyncmy/litestar/store.py +296 -0
- sqlspec/adapters/asyncpg/__init__.py +2 -1
- sqlspec/adapters/asyncpg/_type_handlers.py +71 -0
- sqlspec/adapters/asyncpg/_types.py +11 -7
- sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
- sqlspec/adapters/asyncpg/adk/store.py +450 -0
- sqlspec/adapters/asyncpg/config.py +57 -36
- sqlspec/adapters/asyncpg/data_dictionary.py +41 -2
- sqlspec/adapters/asyncpg/driver.py +153 -23
- sqlspec/adapters/asyncpg/litestar/__init__.py +5 -0
- sqlspec/adapters/asyncpg/litestar/store.py +253 -0
- sqlspec/adapters/bigquery/_types.py +1 -1
- sqlspec/adapters/bigquery/adk/__init__.py +5 -0
- sqlspec/adapters/bigquery/adk/store.py +576 -0
- sqlspec/adapters/bigquery/config.py +25 -11
- sqlspec/adapters/bigquery/data_dictionary.py +42 -2
- sqlspec/adapters/bigquery/driver.py +352 -144
- sqlspec/adapters/bigquery/litestar/__init__.py +5 -0
- sqlspec/adapters/bigquery/litestar/store.py +327 -0
- sqlspec/adapters/bigquery/type_converter.py +55 -23
- sqlspec/adapters/duckdb/_types.py +2 -2
- sqlspec/adapters/duckdb/adk/__init__.py +14 -0
- sqlspec/adapters/duckdb/adk/store.py +553 -0
- sqlspec/adapters/duckdb/config.py +79 -21
- sqlspec/adapters/duckdb/data_dictionary.py +41 -2
- sqlspec/adapters/duckdb/driver.py +138 -43
- sqlspec/adapters/duckdb/litestar/__init__.py +5 -0
- sqlspec/adapters/duckdb/litestar/store.py +332 -0
- sqlspec/adapters/duckdb/pool.py +5 -5
- sqlspec/adapters/duckdb/type_converter.py +51 -21
- sqlspec/adapters/oracledb/_numpy_handlers.py +133 -0
- sqlspec/adapters/oracledb/_types.py +20 -2
- sqlspec/adapters/oracledb/adk/__init__.py +5 -0
- sqlspec/adapters/oracledb/adk/store.py +1745 -0
- sqlspec/adapters/oracledb/config.py +120 -36
- sqlspec/adapters/oracledb/data_dictionary.py +87 -20
- sqlspec/adapters/oracledb/driver.py +292 -84
- sqlspec/adapters/oracledb/litestar/__init__.py +5 -0
- sqlspec/adapters/oracledb/litestar/store.py +767 -0
- sqlspec/adapters/oracledb/migrations.py +316 -25
- sqlspec/adapters/oracledb/type_converter.py +91 -16
- sqlspec/adapters/psqlpy/_type_handlers.py +44 -0
- sqlspec/adapters/psqlpy/_types.py +2 -1
- sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
- sqlspec/adapters/psqlpy/adk/store.py +482 -0
- sqlspec/adapters/psqlpy/config.py +45 -19
- sqlspec/adapters/psqlpy/data_dictionary.py +41 -2
- sqlspec/adapters/psqlpy/driver.py +101 -31
- sqlspec/adapters/psqlpy/litestar/__init__.py +5 -0
- sqlspec/adapters/psqlpy/litestar/store.py +272 -0
- sqlspec/adapters/psqlpy/type_converter.py +40 -11
- sqlspec/adapters/psycopg/_type_handlers.py +80 -0
- sqlspec/adapters/psycopg/_types.py +2 -1
- sqlspec/adapters/psycopg/adk/__init__.py +5 -0
- sqlspec/adapters/psycopg/adk/store.py +944 -0
- sqlspec/adapters/psycopg/config.py +65 -37
- sqlspec/adapters/psycopg/data_dictionary.py +77 -3
- sqlspec/adapters/psycopg/driver.py +200 -78
- sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
- sqlspec/adapters/psycopg/litestar/store.py +554 -0
- sqlspec/adapters/sqlite/__init__.py +2 -1
- sqlspec/adapters/sqlite/_type_handlers.py +86 -0
- sqlspec/adapters/sqlite/_types.py +1 -1
- sqlspec/adapters/sqlite/adk/__init__.py +5 -0
- sqlspec/adapters/sqlite/adk/store.py +572 -0
- sqlspec/adapters/sqlite/config.py +85 -16
- sqlspec/adapters/sqlite/data_dictionary.py +34 -2
- sqlspec/adapters/sqlite/driver.py +120 -52
- sqlspec/adapters/sqlite/litestar/__init__.py +5 -0
- sqlspec/adapters/sqlite/litestar/store.py +318 -0
- sqlspec/adapters/sqlite/pool.py +5 -5
- sqlspec/base.py +45 -26
- sqlspec/builder/__init__.py +73 -4
- sqlspec/builder/_base.py +91 -58
- sqlspec/builder/_column.py +5 -5
- sqlspec/builder/_ddl.py +98 -89
- sqlspec/builder/_delete.py +5 -4
- sqlspec/builder/_dml.py +388 -0
- sqlspec/{_sql.py → builder/_factory.py} +41 -44
- sqlspec/builder/_insert.py +5 -82
- sqlspec/builder/{mixins/_join_operations.py → _join.py} +145 -143
- sqlspec/builder/_merge.py +446 -11
- sqlspec/builder/_parsing_utils.py +9 -11
- sqlspec/builder/_select.py +1313 -25
- sqlspec/builder/_update.py +11 -42
- sqlspec/cli.py +76 -69
- sqlspec/config.py +231 -60
- sqlspec/core/__init__.py +5 -4
- sqlspec/core/cache.py +18 -18
- sqlspec/core/compiler.py +6 -8
- sqlspec/core/filters.py +37 -37
- sqlspec/core/hashing.py +9 -9
- sqlspec/core/parameters.py +76 -45
- sqlspec/core/result.py +102 -46
- sqlspec/core/splitter.py +16 -17
- sqlspec/core/statement.py +32 -31
- sqlspec/core/type_conversion.py +3 -2
- sqlspec/driver/__init__.py +1 -3
- sqlspec/driver/_async.py +95 -161
- sqlspec/driver/_common.py +133 -80
- sqlspec/driver/_sync.py +95 -162
- sqlspec/driver/mixins/_result_tools.py +20 -236
- sqlspec/driver/mixins/_sql_translator.py +4 -4
- sqlspec/exceptions.py +70 -7
- sqlspec/extensions/adk/__init__.py +53 -0
- sqlspec/extensions/adk/_types.py +51 -0
- sqlspec/extensions/adk/converters.py +172 -0
- sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +144 -0
- sqlspec/extensions/adk/migrations/__init__.py +0 -0
- sqlspec/extensions/adk/service.py +181 -0
- sqlspec/extensions/adk/store.py +536 -0
- sqlspec/extensions/aiosql/adapter.py +73 -53
- sqlspec/extensions/litestar/__init__.py +21 -4
- sqlspec/extensions/litestar/cli.py +54 -10
- sqlspec/extensions/litestar/config.py +59 -266
- sqlspec/extensions/litestar/handlers.py +46 -17
- sqlspec/extensions/litestar/migrations/0001_create_session_table.py +137 -0
- sqlspec/extensions/litestar/migrations/__init__.py +3 -0
- sqlspec/extensions/litestar/plugin.py +324 -223
- sqlspec/extensions/litestar/providers.py +25 -25
- sqlspec/extensions/litestar/store.py +265 -0
- sqlspec/loader.py +30 -49
- sqlspec/migrations/base.py +200 -76
- sqlspec/migrations/commands.py +591 -62
- sqlspec/migrations/context.py +6 -9
- sqlspec/migrations/fix.py +199 -0
- sqlspec/migrations/loaders.py +47 -19
- sqlspec/migrations/runner.py +241 -75
- sqlspec/migrations/tracker.py +237 -21
- sqlspec/migrations/utils.py +51 -3
- sqlspec/migrations/validation.py +177 -0
- sqlspec/protocols.py +66 -36
- sqlspec/storage/_utils.py +98 -0
- sqlspec/storage/backends/fsspec.py +134 -106
- sqlspec/storage/backends/local.py +78 -51
- sqlspec/storage/backends/obstore.py +278 -162
- sqlspec/storage/registry.py +75 -39
- sqlspec/typing.py +14 -84
- sqlspec/utils/config_resolver.py +6 -6
- sqlspec/utils/correlation.py +4 -5
- sqlspec/utils/data_transformation.py +3 -2
- sqlspec/utils/deprecation.py +9 -8
- sqlspec/utils/fixtures.py +4 -4
- sqlspec/utils/logging.py +46 -6
- sqlspec/utils/module_loader.py +2 -2
- sqlspec/utils/schema.py +288 -0
- sqlspec/utils/serializers.py +3 -3
- sqlspec/utils/sync_tools.py +21 -17
- sqlspec/utils/text.py +1 -2
- sqlspec/utils/type_guards.py +111 -20
- sqlspec/utils/version.py +433 -0
- {sqlspec-0.26.0.dist-info → sqlspec-0.27.0.dist-info}/METADATA +40 -21
- sqlspec-0.27.0.dist-info/RECORD +207 -0
- sqlspec/builder/mixins/__init__.py +0 -55
- sqlspec/builder/mixins/_cte_and_set_ops.py +0 -253
- sqlspec/builder/mixins/_delete_operations.py +0 -50
- sqlspec/builder/mixins/_insert_operations.py +0 -282
- sqlspec/builder/mixins/_merge_operations.py +0 -698
- sqlspec/builder/mixins/_order_limit_operations.py +0 -145
- sqlspec/builder/mixins/_pivot_operations.py +0 -157
- sqlspec/builder/mixins/_select_operations.py +0 -930
- sqlspec/builder/mixins/_update_operations.py +0 -199
- sqlspec/builder/mixins/_where_clause.py +0 -1298
- sqlspec-0.26.0.dist-info/RECORD +0 -157
- sqlspec-0.26.0.dist-info/licenses/NOTICE +0 -29
- {sqlspec-0.26.0.dist-info → sqlspec-0.27.0.dist-info}/WHEEL +0 -0
- {sqlspec-0.26.0.dist-info → sqlspec-0.27.0.dist-info}/entry_points.txt +0 -0
- {sqlspec-0.26.0.dist-info → sqlspec-0.27.0.dist-info}/licenses/LICENSE +0 -0
sqlspec/driver/_sync.py
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
"""Synchronous driver protocol implementation."""
|
|
2
2
|
|
|
3
3
|
from abc import abstractmethod
|
|
4
|
-
from typing import TYPE_CHECKING, Any, Final,
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Final, TypeVar, overload
|
|
5
5
|
|
|
6
6
|
from sqlspec.core import SQL
|
|
7
|
-
from sqlspec.driver._common import
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
from sqlspec.driver._common import (
|
|
8
|
+
CommonDriverAttributesMixin,
|
|
9
|
+
DataDictionaryMixin,
|
|
10
|
+
ExecutionResult,
|
|
11
|
+
VersionInfo,
|
|
12
|
+
handle_single_row_error,
|
|
13
|
+
)
|
|
14
|
+
from sqlspec.driver.mixins import SQLTranslatorMixin
|
|
10
15
|
from sqlspec.utils.logging import get_logger
|
|
11
|
-
from sqlspec.utils.type_guards import is_dict_row, is_indexable_row
|
|
12
16
|
|
|
13
17
|
if TYPE_CHECKING:
|
|
14
18
|
from collections.abc import Sequence
|
|
@@ -16,7 +20,7 @@ if TYPE_CHECKING:
|
|
|
16
20
|
|
|
17
21
|
from sqlspec.builder import QueryBuilder
|
|
18
22
|
from sqlspec.core import SQLResult, Statement, StatementConfig, StatementFilter
|
|
19
|
-
from sqlspec.typing import
|
|
23
|
+
from sqlspec.typing import SchemaT, StatementParameters
|
|
20
24
|
|
|
21
25
|
_LOGGER_NAME: Final[str] = "sqlspec"
|
|
22
26
|
logger = get_logger(_LOGGER_NAME)
|
|
@@ -29,7 +33,7 @@ EMPTY_FILTERS: Final["list[StatementFilter]"] = []
|
|
|
29
33
|
SyncDriverT = TypeVar("SyncDriverT", bound="SyncDriverAdapterBase")
|
|
30
34
|
|
|
31
35
|
|
|
32
|
-
class SyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin
|
|
36
|
+
class SyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin):
|
|
33
37
|
"""Base class for synchronous database drivers."""
|
|
34
38
|
|
|
35
39
|
__slots__ = ()
|
|
@@ -96,7 +100,7 @@ class SyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, ToS
|
|
|
96
100
|
"""Commit the current transaction on the current connection."""
|
|
97
101
|
|
|
98
102
|
@abstractmethod
|
|
99
|
-
def _try_special_handling(self, cursor: Any, statement: "SQL") -> "
|
|
103
|
+
def _try_special_handling(self, cursor: Any, statement: "SQL") -> "SQLResult | None":
|
|
100
104
|
"""Hook for database-specific special operations (e.g., PostgreSQL COPY, bulk operations).
|
|
101
105
|
|
|
102
106
|
This method is called first in dispatch_statement_execution() to allow drivers to handle
|
|
@@ -169,10 +173,10 @@ class SyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, ToS
|
|
|
169
173
|
|
|
170
174
|
def execute(
|
|
171
175
|
self,
|
|
172
|
-
statement: "
|
|
176
|
+
statement: "SQL | Statement | QueryBuilder",
|
|
173
177
|
/,
|
|
174
|
-
*parameters: "
|
|
175
|
-
statement_config: "
|
|
178
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
179
|
+
statement_config: "StatementConfig | None" = None,
|
|
176
180
|
**kwargs: Any,
|
|
177
181
|
) -> "SQLResult":
|
|
178
182
|
"""Execute a statement with parameter handling."""
|
|
@@ -183,11 +187,11 @@ class SyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, ToS
|
|
|
183
187
|
|
|
184
188
|
def execute_many(
|
|
185
189
|
self,
|
|
186
|
-
statement: "
|
|
190
|
+
statement: "SQL | Statement | QueryBuilder",
|
|
187
191
|
/,
|
|
188
192
|
parameters: "Sequence[StatementParameters]",
|
|
189
|
-
*filters: "
|
|
190
|
-
statement_config: "
|
|
193
|
+
*filters: "StatementParameters | StatementFilter",
|
|
194
|
+
statement_config: "StatementConfig | None" = None,
|
|
191
195
|
**kwargs: Any,
|
|
192
196
|
) -> "SQLResult":
|
|
193
197
|
"""Execute statement multiple times with different parameters.
|
|
@@ -206,10 +210,10 @@ class SyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, ToS
|
|
|
206
210
|
|
|
207
211
|
def execute_script(
|
|
208
212
|
self,
|
|
209
|
-
statement: "
|
|
213
|
+
statement: "str | SQL",
|
|
210
214
|
/,
|
|
211
|
-
*parameters: "
|
|
212
|
-
statement_config: "
|
|
215
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
216
|
+
statement_config: "StatementConfig | None" = None,
|
|
213
217
|
**kwargs: Any,
|
|
214
218
|
) -> "SQLResult":
|
|
215
219
|
"""Execute a multi-statement script.
|
|
@@ -225,140 +229,124 @@ class SyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, ToS
|
|
|
225
229
|
@overload
|
|
226
230
|
def select_one(
|
|
227
231
|
self,
|
|
228
|
-
statement: "
|
|
232
|
+
statement: "Statement | QueryBuilder",
|
|
229
233
|
/,
|
|
230
|
-
*parameters: "
|
|
231
|
-
schema_type: "type[
|
|
232
|
-
statement_config: "
|
|
234
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
235
|
+
schema_type: "type[SchemaT]",
|
|
236
|
+
statement_config: "StatementConfig | None" = None,
|
|
233
237
|
**kwargs: Any,
|
|
234
|
-
) -> "
|
|
238
|
+
) -> "SchemaT": ...
|
|
235
239
|
|
|
236
240
|
@overload
|
|
237
241
|
def select_one(
|
|
238
242
|
self,
|
|
239
|
-
statement: "
|
|
243
|
+
statement: "Statement | QueryBuilder",
|
|
240
244
|
/,
|
|
241
|
-
*parameters: "
|
|
245
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
242
246
|
schema_type: None = None,
|
|
243
|
-
statement_config: "
|
|
247
|
+
statement_config: "StatementConfig | None" = None,
|
|
244
248
|
**kwargs: Any,
|
|
245
249
|
) -> "dict[str, Any]": ...
|
|
246
250
|
|
|
247
251
|
def select_one(
|
|
248
252
|
self,
|
|
249
|
-
statement: "
|
|
253
|
+
statement: "Statement | QueryBuilder",
|
|
250
254
|
/,
|
|
251
|
-
*parameters: "
|
|
252
|
-
schema_type: "
|
|
253
|
-
statement_config: "
|
|
255
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
256
|
+
schema_type: "type[SchemaT] | None" = None,
|
|
257
|
+
statement_config: "StatementConfig | None" = None,
|
|
254
258
|
**kwargs: Any,
|
|
255
|
-
) -> "
|
|
259
|
+
) -> "SchemaT | dict[str, Any]":
|
|
256
260
|
"""Execute a select statement and return exactly one row.
|
|
257
261
|
|
|
258
262
|
Raises an exception if no rows or more than one row is returned.
|
|
259
263
|
"""
|
|
260
264
|
result = self.execute(statement, *parameters, statement_config=statement_config, **kwargs)
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
if data_len > 1:
|
|
266
|
-
self._raise_expected_one_row(data_len)
|
|
267
|
-
first_row = data[0]
|
|
268
|
-
return self.to_schema(first_row, schema_type=schema_type) if schema_type else first_row
|
|
265
|
+
try:
|
|
266
|
+
return result.one(schema_type=schema_type)
|
|
267
|
+
except ValueError as error:
|
|
268
|
+
handle_single_row_error(error)
|
|
269
269
|
|
|
270
270
|
@overload
|
|
271
271
|
def select_one_or_none(
|
|
272
272
|
self,
|
|
273
|
-
statement: "
|
|
273
|
+
statement: "Statement | QueryBuilder",
|
|
274
274
|
/,
|
|
275
|
-
*parameters: "
|
|
276
|
-
schema_type: "type[
|
|
277
|
-
statement_config: "
|
|
275
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
276
|
+
schema_type: "type[SchemaT]",
|
|
277
|
+
statement_config: "StatementConfig | None" = None,
|
|
278
278
|
**kwargs: Any,
|
|
279
|
-
) -> "
|
|
279
|
+
) -> "SchemaT | None": ...
|
|
280
280
|
|
|
281
281
|
@overload
|
|
282
282
|
def select_one_or_none(
|
|
283
283
|
self,
|
|
284
|
-
statement: "
|
|
284
|
+
statement: "Statement | QueryBuilder",
|
|
285
285
|
/,
|
|
286
|
-
*parameters: "
|
|
286
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
287
287
|
schema_type: None = None,
|
|
288
|
-
statement_config: "
|
|
288
|
+
statement_config: "StatementConfig | None" = None,
|
|
289
289
|
**kwargs: Any,
|
|
290
|
-
) -> "
|
|
290
|
+
) -> "dict[str, Any] | None": ...
|
|
291
291
|
|
|
292
292
|
def select_one_or_none(
|
|
293
293
|
self,
|
|
294
|
-
statement: "
|
|
294
|
+
statement: "Statement | QueryBuilder",
|
|
295
295
|
/,
|
|
296
|
-
*parameters: "
|
|
297
|
-
schema_type: "
|
|
298
|
-
statement_config: "
|
|
296
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
297
|
+
schema_type: "type[SchemaT] | None" = None,
|
|
298
|
+
statement_config: "StatementConfig | None" = None,
|
|
299
299
|
**kwargs: Any,
|
|
300
|
-
) -> "
|
|
300
|
+
) -> "SchemaT | dict[str, Any] | None":
|
|
301
301
|
"""Execute a select statement and return at most one row.
|
|
302
302
|
|
|
303
303
|
Returns None if no rows are found.
|
|
304
304
|
Raises an exception if more than one row is returned.
|
|
305
305
|
"""
|
|
306
306
|
result = self.execute(statement, *parameters, statement_config=statement_config, **kwargs)
|
|
307
|
-
|
|
308
|
-
data_len: int = len(data)
|
|
309
|
-
if data_len == 0:
|
|
310
|
-
return None
|
|
311
|
-
if data_len > 1:
|
|
312
|
-
self._raise_expected_at_most_one_row(data_len)
|
|
313
|
-
first_row = data[0]
|
|
314
|
-
return cast(
|
|
315
|
-
"Optional[Union[dict[str, Any], ModelDTOT]]",
|
|
316
|
-
self.to_schema(first_row, schema_type=schema_type) if schema_type else first_row,
|
|
317
|
-
)
|
|
307
|
+
return result.one_or_none(schema_type=schema_type)
|
|
318
308
|
|
|
319
309
|
@overload
|
|
320
310
|
def select(
|
|
321
311
|
self,
|
|
322
|
-
statement: "
|
|
312
|
+
statement: "Statement | QueryBuilder",
|
|
323
313
|
/,
|
|
324
|
-
*parameters: "
|
|
325
|
-
schema_type: "type[
|
|
326
|
-
statement_config: "
|
|
314
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
315
|
+
schema_type: "type[SchemaT]",
|
|
316
|
+
statement_config: "StatementConfig | None" = None,
|
|
327
317
|
**kwargs: Any,
|
|
328
|
-
) -> "list[
|
|
318
|
+
) -> "list[SchemaT]": ...
|
|
329
319
|
|
|
330
320
|
@overload
|
|
331
321
|
def select(
|
|
332
322
|
self,
|
|
333
|
-
statement: "
|
|
323
|
+
statement: "Statement | QueryBuilder",
|
|
334
324
|
/,
|
|
335
|
-
*parameters: "
|
|
325
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
336
326
|
schema_type: None = None,
|
|
337
|
-
statement_config: "
|
|
327
|
+
statement_config: "StatementConfig | None" = None,
|
|
338
328
|
**kwargs: Any,
|
|
339
329
|
) -> "list[dict[str, Any]]": ...
|
|
340
330
|
|
|
341
331
|
def select(
|
|
342
332
|
self,
|
|
343
|
-
statement: "
|
|
333
|
+
statement: "Statement | QueryBuilder",
|
|
344
334
|
/,
|
|
345
|
-
*parameters: "
|
|
346
|
-
schema_type: "
|
|
347
|
-
statement_config: "
|
|
335
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
336
|
+
schema_type: "type[SchemaT] | None" = None,
|
|
337
|
+
statement_config: "StatementConfig | None" = None,
|
|
348
338
|
**kwargs: Any,
|
|
349
|
-
) -> "
|
|
339
|
+
) -> "list[SchemaT] | list[dict[str, Any]]":
|
|
350
340
|
"""Execute a select statement and return all rows."""
|
|
351
341
|
result = self.execute(statement, *parameters, statement_config=statement_config, **kwargs)
|
|
352
|
-
return
|
|
353
|
-
"Union[list[dict[str, Any]], list[ModelDTOT]]", self.to_schema(result.get_data(), schema_type=schema_type)
|
|
354
|
-
)
|
|
342
|
+
return result.get_data(schema_type=schema_type)
|
|
355
343
|
|
|
356
344
|
def select_value(
|
|
357
345
|
self,
|
|
358
|
-
statement: "
|
|
346
|
+
statement: "Statement | QueryBuilder",
|
|
359
347
|
/,
|
|
360
|
-
*parameters: "
|
|
361
|
-
statement_config: "
|
|
348
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
349
|
+
statement_config: "StatementConfig | None" = None,
|
|
362
350
|
**kwargs: Any,
|
|
363
351
|
) -> Any:
|
|
364
352
|
"""Execute a select statement and return a single scalar value.
|
|
@@ -368,28 +356,16 @@ class SyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, ToS
|
|
|
368
356
|
"""
|
|
369
357
|
result = self.execute(statement, *parameters, statement_config=statement_config, **kwargs)
|
|
370
358
|
try:
|
|
371
|
-
|
|
372
|
-
except ValueError as
|
|
373
|
-
|
|
374
|
-
if not row:
|
|
375
|
-
self._raise_no_rows_found()
|
|
376
|
-
if is_dict_row(row):
|
|
377
|
-
if not row:
|
|
378
|
-
self._raise_row_no_columns()
|
|
379
|
-
return next(iter(row.values()))
|
|
380
|
-
if is_indexable_row(row):
|
|
381
|
-
if not row:
|
|
382
|
-
self._raise_row_no_columns()
|
|
383
|
-
return row[0]
|
|
384
|
-
self._raise_unexpected_row_type(type(row))
|
|
385
|
-
return None
|
|
359
|
+
return result.scalar()
|
|
360
|
+
except ValueError as error:
|
|
361
|
+
handle_single_row_error(error)
|
|
386
362
|
|
|
387
363
|
def select_value_or_none(
|
|
388
364
|
self,
|
|
389
|
-
statement: "
|
|
365
|
+
statement: "Statement | QueryBuilder",
|
|
390
366
|
/,
|
|
391
|
-
*parameters: "
|
|
392
|
-
statement_config: "
|
|
367
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
368
|
+
statement_config: "StatementConfig | None" = None,
|
|
393
369
|
**kwargs: Any,
|
|
394
370
|
) -> Any:
|
|
395
371
|
"""Execute a select statement and return a single scalar value or None.
|
|
@@ -399,54 +375,39 @@ class SyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, ToS
|
|
|
399
375
|
Raises an exception if more than one row is returned.
|
|
400
376
|
"""
|
|
401
377
|
result = self.execute(statement, *parameters, statement_config=statement_config, **kwargs)
|
|
402
|
-
|
|
403
|
-
data_len: int = len(data)
|
|
404
|
-
if data_len == 0:
|
|
405
|
-
return None
|
|
406
|
-
if data_len > 1:
|
|
407
|
-
msg = f"Expected at most one row, found {data_len}"
|
|
408
|
-
raise ValueError(msg)
|
|
409
|
-
row = data[0]
|
|
410
|
-
if isinstance(row, dict):
|
|
411
|
-
if not row:
|
|
412
|
-
return None
|
|
413
|
-
return next(iter(row.values()))
|
|
414
|
-
if isinstance(row, (tuple, list)):
|
|
415
|
-
return row[0]
|
|
416
|
-
msg = f"Cannot extract value from row type {type(row).__name__}"
|
|
417
|
-
raise TypeError(msg)
|
|
378
|
+
return result.scalar_or_none()
|
|
418
379
|
|
|
419
380
|
@overload
|
|
420
381
|
def select_with_total(
|
|
421
382
|
self,
|
|
422
|
-
statement: "
|
|
383
|
+
statement: "Statement | QueryBuilder",
|
|
423
384
|
/,
|
|
424
|
-
*parameters: "
|
|
425
|
-
schema_type: "type[
|
|
426
|
-
statement_config: "
|
|
385
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
386
|
+
schema_type: "type[SchemaT]",
|
|
387
|
+
statement_config: "StatementConfig | None" = None,
|
|
427
388
|
**kwargs: Any,
|
|
428
|
-
) -> "tuple[list[
|
|
389
|
+
) -> "tuple[list[SchemaT], int]": ...
|
|
429
390
|
|
|
430
391
|
@overload
|
|
431
392
|
def select_with_total(
|
|
432
393
|
self,
|
|
433
|
-
statement: "
|
|
394
|
+
statement: "Statement | QueryBuilder",
|
|
434
395
|
/,
|
|
435
|
-
*parameters: "
|
|
396
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
436
397
|
schema_type: None = None,
|
|
437
|
-
statement_config: "
|
|
398
|
+
statement_config: "StatementConfig | None" = None,
|
|
438
399
|
**kwargs: Any,
|
|
439
400
|
) -> "tuple[list[dict[str, Any]], int]": ...
|
|
440
401
|
|
|
441
402
|
def select_with_total(
|
|
442
403
|
self,
|
|
443
|
-
statement: "
|
|
404
|
+
statement: "Statement | QueryBuilder",
|
|
444
405
|
/,
|
|
445
|
-
*parameters: "
|
|
446
|
-
schema_type: "
|
|
447
|
-
statement_config: "
|
|
406
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
407
|
+
schema_type: "type[SchemaT] | None" = None,
|
|
408
|
+
statement_config: "StatementConfig | None" = None,
|
|
448
409
|
**kwargs: Any,
|
|
449
|
-
) -> "tuple[
|
|
410
|
+
) -> "tuple[list[SchemaT] | list[dict[str, Any]], int]":
|
|
450
411
|
"""Execute a select statement and return both the data and total count.
|
|
451
412
|
|
|
452
413
|
This method is designed for pagination scenarios where you need both
|
|
@@ -470,42 +431,14 @@ class SyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, ToS
|
|
|
470
431
|
count_result = self.dispatch_statement_execution(self._create_count_query(sql_statement), self.connection)
|
|
471
432
|
select_result = self.execute(sql_statement)
|
|
472
433
|
|
|
473
|
-
return (
|
|
474
|
-
|
|
475
|
-
def _raise_no_rows_found(self) -> NoReturn:
|
|
476
|
-
msg = "No rows found"
|
|
477
|
-
raise NotFoundError(msg)
|
|
478
|
-
|
|
479
|
-
def _raise_no_rows_found_from_exception(self, e: ValueError) -> NoReturn:
|
|
480
|
-
msg = "No rows found"
|
|
481
|
-
raise NotFoundError(msg) from e
|
|
482
|
-
|
|
483
|
-
def _raise_expected_one_row(self, data_len: int) -> NoReturn:
|
|
484
|
-
msg = f"Expected exactly one row, found {data_len}"
|
|
485
|
-
raise ValueError(msg)
|
|
486
|
-
|
|
487
|
-
def _raise_expected_at_most_one_row(self, data_len: int) -> NoReturn:
|
|
488
|
-
msg = f"Expected at most one row, found {data_len}"
|
|
489
|
-
raise ValueError(msg)
|
|
490
|
-
|
|
491
|
-
def _raise_row_no_columns(self) -> NoReturn:
|
|
492
|
-
msg = "Row has no columns"
|
|
493
|
-
raise ValueError(msg)
|
|
494
|
-
|
|
495
|
-
def _raise_unexpected_row_type(self, row_type: type) -> NoReturn:
|
|
496
|
-
msg = f"Unexpected row type: {row_type}"
|
|
497
|
-
raise ValueError(msg)
|
|
498
|
-
|
|
499
|
-
def _raise_cannot_extract_value_from_row_type(self, type_name: str) -> NoReturn:
|
|
500
|
-
msg = f"Cannot extract value from row type {type_name}"
|
|
501
|
-
raise TypeError(msg)
|
|
434
|
+
return (select_result.get_data(schema_type=schema_type), count_result.scalar())
|
|
502
435
|
|
|
503
436
|
|
|
504
437
|
class SyncDataDictionaryBase(DataDictionaryMixin):
|
|
505
438
|
"""Base class for synchronous data dictionary implementations."""
|
|
506
439
|
|
|
507
440
|
@abstractmethod
|
|
508
|
-
def get_version(self, driver: "SyncDriverAdapterBase") -> "
|
|
441
|
+
def get_version(self, driver: "SyncDriverAdapterBase") -> "VersionInfo | None":
|
|
509
442
|
"""Get database version information.
|
|
510
443
|
|
|
511
444
|
Args:
|
|
@@ -539,7 +472,7 @@ class SyncDataDictionaryBase(DataDictionaryMixin):
|
|
|
539
472
|
Database-specific type name
|
|
540
473
|
"""
|
|
541
474
|
|
|
542
|
-
def get_tables(self, driver: "SyncDriverAdapterBase", schema: "
|
|
475
|
+
def get_tables(self, driver: "SyncDriverAdapterBase", schema: "str | None" = None) -> "list[str]":
|
|
543
476
|
"""Get list of tables in schema.
|
|
544
477
|
|
|
545
478
|
Args:
|
|
@@ -553,7 +486,7 @@ class SyncDataDictionaryBase(DataDictionaryMixin):
|
|
|
553
486
|
return []
|
|
554
487
|
|
|
555
488
|
def get_columns(
|
|
556
|
-
self, driver: "SyncDriverAdapterBase", table: str, schema: "
|
|
489
|
+
self, driver: "SyncDriverAdapterBase", table: str, schema: "str | None" = None
|
|
557
490
|
) -> "list[dict[str, Any]]":
|
|
558
491
|
"""Get column information for a table.
|
|
559
492
|
|
|
@@ -569,7 +502,7 @@ class SyncDataDictionaryBase(DataDictionaryMixin):
|
|
|
569
502
|
return []
|
|
570
503
|
|
|
571
504
|
def get_indexes(
|
|
572
|
-
self, driver: "SyncDriverAdapterBase", table: str, schema: "
|
|
505
|
+
self, driver: "SyncDriverAdapterBase", table: str, schema: "str | None" = None
|
|
573
506
|
) -> "list[dict[str, Any]]":
|
|
574
507
|
"""Get index information for a table.
|
|
575
508
|
|