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/_async.py
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
"""Asynchronous 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, Statement
|
|
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, 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
|
AsyncDriverT = TypeVar("AsyncDriverT", bound="AsyncDriverAdapterBase")
|
|
30
34
|
|
|
31
35
|
|
|
32
|
-
class AsyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin
|
|
36
|
+
class AsyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin):
|
|
33
37
|
"""Base class for asynchronous database drivers."""
|
|
34
38
|
|
|
35
39
|
__slots__ = ()
|
|
@@ -96,7 +100,7 @@ class AsyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, To
|
|
|
96
100
|
"""Commit the current transaction on the current connection."""
|
|
97
101
|
|
|
98
102
|
@abstractmethod
|
|
99
|
-
async def _try_special_handling(self, cursor: Any, statement: "SQL") -> "
|
|
103
|
+
async 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 AsyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, To
|
|
|
169
173
|
|
|
170
174
|
async 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 AsyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, To
|
|
|
183
187
|
|
|
184
188
|
async 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 AsyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, To
|
|
|
206
210
|
|
|
207
211
|
async 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 AsyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, To
|
|
|
225
229
|
@overload
|
|
226
230
|
async 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
|
async 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
|
async 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 = await 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
|
async 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
|
async 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
|
async 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 = await 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
|
async 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
|
async 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
|
async 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 = await 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
|
async 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 AsyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, To
|
|
|
368
356
|
"""
|
|
369
357
|
result = await 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
|
async 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,53 +375,39 @@ class AsyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, To
|
|
|
399
375
|
Raises an exception if more than one row is returned.
|
|
400
376
|
"""
|
|
401
377
|
result = await 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
|
-
self._raise_expected_at_most_one_row(data_len)
|
|
408
|
-
row = data[0]
|
|
409
|
-
if is_dict_row(row):
|
|
410
|
-
if not row:
|
|
411
|
-
return None
|
|
412
|
-
return next(iter(row.values()))
|
|
413
|
-
if is_indexable_row(row):
|
|
414
|
-
return row[0]
|
|
415
|
-
self._raise_cannot_extract_value_from_row_type(type(row).__name__)
|
|
416
|
-
return None
|
|
378
|
+
return result.scalar_or_none()
|
|
417
379
|
|
|
418
380
|
@overload
|
|
419
381
|
async def select_with_total(
|
|
420
382
|
self,
|
|
421
|
-
statement: "
|
|
383
|
+
statement: "Statement | QueryBuilder",
|
|
422
384
|
/,
|
|
423
|
-
*parameters: "
|
|
424
|
-
schema_type: "type[
|
|
425
|
-
statement_config: "
|
|
385
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
386
|
+
schema_type: "type[SchemaT]",
|
|
387
|
+
statement_config: "StatementConfig | None" = None,
|
|
426
388
|
**kwargs: Any,
|
|
427
|
-
) -> "tuple[list[
|
|
389
|
+
) -> "tuple[list[SchemaT], int]": ...
|
|
428
390
|
|
|
429
391
|
@overload
|
|
430
392
|
async def select_with_total(
|
|
431
393
|
self,
|
|
432
|
-
statement: "
|
|
394
|
+
statement: "Statement | QueryBuilder",
|
|
433
395
|
/,
|
|
434
|
-
*parameters: "
|
|
396
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
435
397
|
schema_type: None = None,
|
|
436
|
-
statement_config: "
|
|
398
|
+
statement_config: "StatementConfig | None" = None,
|
|
437
399
|
**kwargs: Any,
|
|
438
400
|
) -> "tuple[list[dict[str, Any]], int]": ...
|
|
439
401
|
|
|
440
402
|
async def select_with_total(
|
|
441
403
|
self,
|
|
442
|
-
statement: "
|
|
404
|
+
statement: "Statement | QueryBuilder",
|
|
443
405
|
/,
|
|
444
|
-
*parameters: "
|
|
445
|
-
schema_type: "
|
|
446
|
-
statement_config: "
|
|
406
|
+
*parameters: "StatementParameters | StatementFilter",
|
|
407
|
+
schema_type: "type[SchemaT] | None" = None,
|
|
408
|
+
statement_config: "StatementConfig | None" = None,
|
|
447
409
|
**kwargs: Any,
|
|
448
|
-
) -> "tuple[
|
|
410
|
+
) -> "tuple[list[SchemaT] | list[dict[str, Any]], int]":
|
|
449
411
|
"""Execute a select statement and return both the data and total count.
|
|
450
412
|
|
|
451
413
|
This method is designed for pagination scenarios where you need both
|
|
@@ -469,42 +431,14 @@ class AsyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, To
|
|
|
469
431
|
count_result = await self.dispatch_statement_execution(self._create_count_query(sql_statement), self.connection)
|
|
470
432
|
select_result = await self.execute(sql_statement)
|
|
471
433
|
|
|
472
|
-
return (
|
|
473
|
-
|
|
474
|
-
def _raise_no_rows_found(self) -> NoReturn:
|
|
475
|
-
msg = "No rows found"
|
|
476
|
-
raise NotFoundError(msg)
|
|
477
|
-
|
|
478
|
-
def _raise_no_rows_found_from_exception(self, e: ValueError) -> NoReturn:
|
|
479
|
-
msg = "No rows found"
|
|
480
|
-
raise NotFoundError(msg) from e
|
|
481
|
-
|
|
482
|
-
def _raise_expected_one_row(self, data_len: int) -> NoReturn:
|
|
483
|
-
msg = f"Expected exactly one row, found {data_len}"
|
|
484
|
-
raise ValueError(msg)
|
|
485
|
-
|
|
486
|
-
def _raise_expected_at_most_one_row(self, data_len: int) -> NoReturn:
|
|
487
|
-
msg = f"Expected at most one row, found {data_len}"
|
|
488
|
-
raise ValueError(msg)
|
|
489
|
-
|
|
490
|
-
def _raise_row_no_columns(self) -> NoReturn:
|
|
491
|
-
msg = "Row has no columns"
|
|
492
|
-
raise ValueError(msg)
|
|
493
|
-
|
|
494
|
-
def _raise_unexpected_row_type(self, row_type: type) -> NoReturn:
|
|
495
|
-
msg = f"Unexpected row type: {row_type}"
|
|
496
|
-
raise ValueError(msg)
|
|
497
|
-
|
|
498
|
-
def _raise_cannot_extract_value_from_row_type(self, type_name: str) -> NoReturn:
|
|
499
|
-
msg = f"Cannot extract value from row type {type_name}"
|
|
500
|
-
raise TypeError(msg)
|
|
434
|
+
return (select_result.get_data(schema_type=schema_type), count_result.scalar())
|
|
501
435
|
|
|
502
436
|
|
|
503
437
|
class AsyncDataDictionaryBase(DataDictionaryMixin):
|
|
504
438
|
"""Base class for asynchronous data dictionary implementations."""
|
|
505
439
|
|
|
506
440
|
@abstractmethod
|
|
507
|
-
async def get_version(self, driver: "AsyncDriverAdapterBase") -> "
|
|
441
|
+
async def get_version(self, driver: "AsyncDriverAdapterBase") -> "VersionInfo | None":
|
|
508
442
|
"""Get database version information.
|
|
509
443
|
|
|
510
444
|
Args:
|
|
@@ -538,7 +472,7 @@ class AsyncDataDictionaryBase(DataDictionaryMixin):
|
|
|
538
472
|
Database-specific type name
|
|
539
473
|
"""
|
|
540
474
|
|
|
541
|
-
async def get_tables(self, driver: "AsyncDriverAdapterBase", schema: "
|
|
475
|
+
async def get_tables(self, driver: "AsyncDriverAdapterBase", schema: "str | None" = None) -> "list[str]":
|
|
542
476
|
"""Get list of tables in schema.
|
|
543
477
|
|
|
544
478
|
Args:
|
|
@@ -552,7 +486,7 @@ class AsyncDataDictionaryBase(DataDictionaryMixin):
|
|
|
552
486
|
return []
|
|
553
487
|
|
|
554
488
|
async def get_columns(
|
|
555
|
-
self, driver: "AsyncDriverAdapterBase", table: str, schema: "
|
|
489
|
+
self, driver: "AsyncDriverAdapterBase", table: str, schema: "str | None" = None
|
|
556
490
|
) -> "list[dict[str, Any]]":
|
|
557
491
|
"""Get column information for a table.
|
|
558
492
|
|
|
@@ -568,7 +502,7 @@ class AsyncDataDictionaryBase(DataDictionaryMixin):
|
|
|
568
502
|
return []
|
|
569
503
|
|
|
570
504
|
async def get_indexes(
|
|
571
|
-
self, driver: "AsyncDriverAdapterBase", table: str, schema: "
|
|
505
|
+
self, driver: "AsyncDriverAdapterBase", table: str, schema: "str | None" = None
|
|
572
506
|
) -> "list[dict[str, Any]]":
|
|
573
507
|
"""Get index information for a table.
|
|
574
508
|
|