sqlspec 0.8.0__py3-none-any.whl → 0.9.1__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/_typing.py +39 -6
- sqlspec/adapters/adbc/__init__.py +2 -2
- sqlspec/adapters/adbc/config.py +34 -11
- sqlspec/adapters/adbc/driver.py +302 -111
- sqlspec/adapters/aiosqlite/__init__.py +2 -2
- sqlspec/adapters/aiosqlite/config.py +2 -2
- sqlspec/adapters/aiosqlite/driver.py +164 -42
- sqlspec/adapters/asyncmy/__init__.py +3 -3
- sqlspec/adapters/asyncmy/config.py +11 -12
- sqlspec/adapters/asyncmy/driver.py +161 -37
- sqlspec/adapters/asyncpg/__init__.py +5 -5
- sqlspec/adapters/asyncpg/config.py +17 -19
- sqlspec/adapters/asyncpg/driver.py +386 -96
- sqlspec/adapters/duckdb/__init__.py +2 -2
- sqlspec/adapters/duckdb/config.py +2 -2
- sqlspec/adapters/duckdb/driver.py +190 -60
- sqlspec/adapters/oracledb/__init__.py +8 -8
- sqlspec/adapters/oracledb/config/__init__.py +6 -6
- sqlspec/adapters/oracledb/config/_asyncio.py +9 -10
- sqlspec/adapters/oracledb/config/_sync.py +8 -9
- sqlspec/adapters/oracledb/driver.py +384 -45
- sqlspec/adapters/psqlpy/__init__.py +0 -0
- sqlspec/adapters/psqlpy/config.py +250 -0
- sqlspec/adapters/psqlpy/driver.py +481 -0
- sqlspec/adapters/psycopg/__init__.py +10 -5
- sqlspec/adapters/psycopg/config/__init__.py +6 -6
- sqlspec/adapters/psycopg/config/_async.py +12 -12
- sqlspec/adapters/psycopg/config/_sync.py +13 -13
- sqlspec/adapters/psycopg/driver.py +432 -222
- sqlspec/adapters/sqlite/__init__.py +2 -2
- sqlspec/adapters/sqlite/config.py +2 -2
- sqlspec/adapters/sqlite/driver.py +176 -72
- sqlspec/base.py +687 -161
- sqlspec/exceptions.py +30 -0
- sqlspec/extensions/litestar/config.py +6 -0
- sqlspec/extensions/litestar/handlers.py +25 -0
- sqlspec/extensions/litestar/plugin.py +8 -1
- sqlspec/statement.py +373 -0
- sqlspec/typing.py +10 -1
- {sqlspec-0.8.0.dist-info → sqlspec-0.9.1.dist-info}/METADATA +144 -2
- sqlspec-0.9.1.dist-info/RECORD +61 -0
- sqlspec-0.8.0.dist-info/RECORD +0 -57
- {sqlspec-0.8.0.dist-info → sqlspec-0.9.1.dist-info}/WHEEL +0 -0
- {sqlspec-0.8.0.dist-info → sqlspec-0.9.1.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.8.0.dist-info → sqlspec-0.9.1.dist-info}/licenses/NOTICE +0 -0
sqlspec/base.py
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# ruff: noqa: PLR6301
|
|
2
|
+
import atexit
|
|
3
|
+
import contextlib
|
|
2
4
|
import re
|
|
3
5
|
from abc import ABC, abstractmethod
|
|
4
|
-
from collections.abc import
|
|
5
|
-
from contextlib import AbstractAsyncContextManager, AbstractContextManager
|
|
6
|
+
from collections.abc import Awaitable, Sequence
|
|
6
7
|
from dataclasses import dataclass, field
|
|
7
8
|
from typing import (
|
|
9
|
+
TYPE_CHECKING,
|
|
8
10
|
Annotated,
|
|
9
11
|
Any,
|
|
10
12
|
ClassVar,
|
|
@@ -17,15 +19,29 @@ from typing import (
|
|
|
17
19
|
)
|
|
18
20
|
|
|
19
21
|
from sqlspec.exceptions import NotFoundError
|
|
22
|
+
from sqlspec.statement import SQLStatement
|
|
20
23
|
from sqlspec.typing import ModelDTOT, StatementParameterType
|
|
24
|
+
from sqlspec.utils.sync_tools import maybe_async_
|
|
25
|
+
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from contextlib import AbstractAsyncContextManager, AbstractContextManager
|
|
28
|
+
|
|
29
|
+
from pyarrow import Table as ArrowTable
|
|
21
30
|
|
|
22
31
|
__all__ = (
|
|
32
|
+
"AsyncArrowBulkOperationsMixin",
|
|
23
33
|
"AsyncDatabaseConfig",
|
|
34
|
+
"AsyncDriverAdapterProtocol",
|
|
35
|
+
"CommonDriverAttributes",
|
|
24
36
|
"DatabaseConfigProtocol",
|
|
25
37
|
"GenericPoolConfig",
|
|
26
38
|
"NoPoolAsyncConfig",
|
|
27
39
|
"NoPoolSyncConfig",
|
|
40
|
+
"SQLSpec",
|
|
41
|
+
"SQLStatement",
|
|
42
|
+
"SyncArrowBulkOperationsMixin",
|
|
28
43
|
"SyncDatabaseConfig",
|
|
44
|
+
"SyncDriverAdapterProtocol",
|
|
29
45
|
)
|
|
30
46
|
|
|
31
47
|
T = TypeVar("T")
|
|
@@ -39,13 +55,15 @@ ConfigT = TypeVar(
|
|
|
39
55
|
bound="Union[Union[AsyncDatabaseConfig[Any, Any, Any], NoPoolAsyncConfig[Any, Any]], SyncDatabaseConfig[Any, Any, Any], NoPoolSyncConfig[Any, Any]]",
|
|
40
56
|
)
|
|
41
57
|
DriverT = TypeVar("DriverT", bound="Union[SyncDriverAdapterProtocol[Any], AsyncDriverAdapterProtocol[Any]]")
|
|
42
|
-
|
|
43
|
-
# Regex to find :param style placeholders, avoiding those inside quotes
|
|
44
|
-
# Handles basic cases, might need refinement for complex SQL
|
|
58
|
+
# Regex to find :param or %(param)s style placeholders, skipping those inside quotes
|
|
45
59
|
PARAM_REGEX = re.compile(
|
|
46
|
-
r"
|
|
47
|
-
|
|
48
|
-
|
|
60
|
+
r"""
|
|
61
|
+
(?P<dquote>"([^"]|\\")*") | # Double-quoted strings
|
|
62
|
+
(?P<squote>'([^']|\\')*') | # Single-quoted strings
|
|
63
|
+
: (?P<var_name_colon>[a-zA-Z_][a-zA-Z0-9_]*) | # :var_name
|
|
64
|
+
% \( (?P<var_name_perc>[a-zA-Z_][a-zA-Z0-9_]*) \) s # %(var_name)s
|
|
65
|
+
""",
|
|
66
|
+
re.VERBOSE,
|
|
49
67
|
)
|
|
50
68
|
|
|
51
69
|
|
|
@@ -56,14 +74,14 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
|
|
|
56
74
|
connection_type: "type[ConnectionT]" = field(init=False)
|
|
57
75
|
driver_type: "type[DriverT]" = field(init=False)
|
|
58
76
|
pool_instance: "Optional[PoolT]" = field(default=None)
|
|
59
|
-
__is_async__: ClassVar[bool] = False
|
|
60
|
-
__supports_connection_pooling__: ClassVar[bool] = False
|
|
77
|
+
__is_async__: "ClassVar[bool]" = False
|
|
78
|
+
__supports_connection_pooling__: "ClassVar[bool]" = False
|
|
61
79
|
|
|
62
80
|
def __hash__(self) -> int:
|
|
63
81
|
return id(self)
|
|
64
82
|
|
|
65
83
|
@abstractmethod
|
|
66
|
-
def create_connection(self) -> Union[ConnectionT, Awaitable[ConnectionT]]:
|
|
84
|
+
def create_connection(self) -> "Union[ConnectionT, Awaitable[ConnectionT]]":
|
|
67
85
|
"""Create and return a new database connection."""
|
|
68
86
|
raise NotImplementedError
|
|
69
87
|
|
|
@@ -72,28 +90,32 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
|
|
|
72
90
|
self,
|
|
73
91
|
*args: Any,
|
|
74
92
|
**kwargs: Any,
|
|
75
|
-
) -> Union[
|
|
76
|
-
Generator[ConnectionT, None, None],
|
|
77
|
-
AsyncGenerator[ConnectionT, None],
|
|
78
|
-
AbstractContextManager[ConnectionT],
|
|
79
|
-
AbstractAsyncContextManager[ConnectionT],
|
|
80
|
-
]:
|
|
93
|
+
) -> "Union[AbstractContextManager[ConnectionT], AbstractAsyncContextManager[ConnectionT]]":
|
|
81
94
|
"""Provide a database connection context manager."""
|
|
82
95
|
raise NotImplementedError
|
|
83
96
|
|
|
97
|
+
@abstractmethod
|
|
98
|
+
def provide_session(
|
|
99
|
+
self,
|
|
100
|
+
*args: Any,
|
|
101
|
+
**kwargs: Any,
|
|
102
|
+
) -> "Union[AbstractContextManager[DriverT], AbstractAsyncContextManager[DriverT]]":
|
|
103
|
+
"""Provide a database session context manager."""
|
|
104
|
+
raise NotImplementedError
|
|
105
|
+
|
|
84
106
|
@property
|
|
85
107
|
@abstractmethod
|
|
86
|
-
def connection_config_dict(self) -> dict[str, Any]:
|
|
108
|
+
def connection_config_dict(self) -> "dict[str, Any]":
|
|
87
109
|
"""Return the connection configuration as a dict."""
|
|
88
110
|
raise NotImplementedError
|
|
89
111
|
|
|
90
112
|
@abstractmethod
|
|
91
|
-
def create_pool(self) -> Union[PoolT, Awaitable[PoolT]]:
|
|
113
|
+
def create_pool(self) -> "Union[PoolT, Awaitable[PoolT]]":
|
|
92
114
|
"""Create and return connection pool."""
|
|
93
115
|
raise NotImplementedError
|
|
94
116
|
|
|
95
117
|
@abstractmethod
|
|
96
|
-
def close_pool(self) -> Optional[Awaitable[None]]:
|
|
118
|
+
def close_pool(self) -> "Optional[Awaitable[None]]":
|
|
97
119
|
"""Terminate the connection pool."""
|
|
98
120
|
raise NotImplementedError
|
|
99
121
|
|
|
@@ -102,7 +124,7 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
|
|
|
102
124
|
self,
|
|
103
125
|
*args: Any,
|
|
104
126
|
**kwargs: Any,
|
|
105
|
-
) -> Union[PoolT, Awaitable[PoolT], AbstractContextManager[PoolT], AbstractAsyncContextManager[PoolT]]:
|
|
127
|
+
) -> "Union[PoolT, Awaitable[PoolT], AbstractContextManager[PoolT], AbstractAsyncContextManager[PoolT]]":
|
|
106
128
|
"""Provide pool instance."""
|
|
107
129
|
raise NotImplementedError
|
|
108
130
|
|
|
@@ -183,20 +205,26 @@ class SQLSpec:
|
|
|
183
205
|
|
|
184
206
|
def __init__(self) -> None:
|
|
185
207
|
self._configs: dict[Any, DatabaseConfigProtocol[Any, Any, Any]] = {}
|
|
208
|
+
# Register the cleanup handler to run at program exit
|
|
209
|
+
atexit.register(self._cleanup_pools)
|
|
210
|
+
|
|
211
|
+
def _cleanup_pools(self) -> None:
|
|
212
|
+
"""Clean up all open database pools at program exit."""
|
|
213
|
+
for config in self._configs.values():
|
|
214
|
+
if config.support_connection_pooling and config.pool_instance is not None:
|
|
215
|
+
with contextlib.suppress(Exception):
|
|
216
|
+
maybe_async_(config.close_pool)()
|
|
186
217
|
|
|
187
218
|
@overload
|
|
188
|
-
def add_config(self, config: SyncConfigT) -> type[SyncConfigT]: ...
|
|
219
|
+
def add_config(self, config: "SyncConfigT") -> "type[SyncConfigT]": ...
|
|
189
220
|
|
|
190
221
|
@overload
|
|
191
|
-
def add_config(self, config: AsyncConfigT) -> type[AsyncConfigT]: ...
|
|
222
|
+
def add_config(self, config: "AsyncConfigT") -> "type[AsyncConfigT]": ...
|
|
192
223
|
|
|
193
224
|
def add_config(
|
|
194
225
|
self,
|
|
195
|
-
config: Union[
|
|
196
|
-
|
|
197
|
-
AsyncConfigT,
|
|
198
|
-
],
|
|
199
|
-
) -> Union[Annotated[type[SyncConfigT], int], Annotated[type[AsyncConfigT], int]]: # pyright: ignore[reportInvalidTypeVarUse]
|
|
226
|
+
config: "Union[SyncConfigT, AsyncConfigT]",
|
|
227
|
+
) -> "Union[Annotated[type[SyncConfigT], int], Annotated[type[AsyncConfigT], int]]": # pyright: ignore[reportInvalidTypeVarUse]
|
|
200
228
|
"""Add a new configuration to the manager.
|
|
201
229
|
|
|
202
230
|
Returns:
|
|
@@ -207,15 +235,15 @@ class SQLSpec:
|
|
|
207
235
|
return key # type: ignore[return-value] # pyright: ignore[reportReturnType]
|
|
208
236
|
|
|
209
237
|
@overload
|
|
210
|
-
def get_config(self, name: type[SyncConfigT]) -> SyncConfigT: ...
|
|
238
|
+
def get_config(self, name: "type[SyncConfigT]") -> "SyncConfigT": ...
|
|
211
239
|
|
|
212
240
|
@overload
|
|
213
|
-
def get_config(self, name: type[AsyncConfigT]) -> AsyncConfigT: ...
|
|
241
|
+
def get_config(self, name: "type[AsyncConfigT]") -> "AsyncConfigT": ...
|
|
214
242
|
|
|
215
243
|
def get_config(
|
|
216
244
|
self,
|
|
217
|
-
name: Union[type[DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]], Any],
|
|
218
|
-
) -> DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]:
|
|
245
|
+
name: "Union[type[DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]], Any]",
|
|
246
|
+
) -> "DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]":
|
|
219
247
|
"""Retrieve a configuration by its type.
|
|
220
248
|
|
|
221
249
|
Returns:
|
|
@@ -234,61 +262,197 @@ class SQLSpec:
|
|
|
234
262
|
def get_connection(
|
|
235
263
|
self,
|
|
236
264
|
name: Union[
|
|
237
|
-
type[NoPoolSyncConfig[ConnectionT, DriverT]],
|
|
238
|
-
type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]], # pyright: ignore[reportInvalidTypeVarUse]
|
|
265
|
+
"type[NoPoolSyncConfig[ConnectionT, DriverT]]",
|
|
266
|
+
"type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]", # pyright: ignore[reportInvalidTypeVarUse]
|
|
239
267
|
],
|
|
240
|
-
) -> ConnectionT: ...
|
|
268
|
+
) -> "ConnectionT": ...
|
|
241
269
|
|
|
242
270
|
@overload
|
|
243
271
|
def get_connection(
|
|
244
272
|
self,
|
|
245
273
|
name: Union[
|
|
246
|
-
type[NoPoolAsyncConfig[ConnectionT, DriverT]],
|
|
247
|
-
type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]], # pyright: ignore[reportInvalidTypeVarUse]
|
|
274
|
+
"type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
|
|
275
|
+
"type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]", # pyright: ignore[reportInvalidTypeVarUse]
|
|
248
276
|
],
|
|
249
|
-
) -> Awaitable[ConnectionT]: ...
|
|
277
|
+
) -> "Awaitable[ConnectionT]": ...
|
|
250
278
|
|
|
251
279
|
def get_connection(
|
|
252
280
|
self,
|
|
253
281
|
name: Union[
|
|
254
|
-
type[NoPoolSyncConfig[ConnectionT, DriverT]],
|
|
255
|
-
type[NoPoolAsyncConfig[ConnectionT, DriverT]],
|
|
256
|
-
type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]],
|
|
257
|
-
type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]],
|
|
282
|
+
"type[NoPoolSyncConfig[ConnectionT, DriverT]]",
|
|
283
|
+
"type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
|
|
284
|
+
"type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
285
|
+
"type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
258
286
|
],
|
|
259
|
-
) -> Union[ConnectionT, Awaitable[ConnectionT]]:
|
|
260
|
-
"""Create and return a connection from the specified configuration.
|
|
287
|
+
) -> "Union[ConnectionT, Awaitable[ConnectionT]]":
|
|
288
|
+
"""Create and return a new database connection from the specified configuration.
|
|
261
289
|
|
|
262
290
|
Args:
|
|
263
291
|
name: The configuration type to use for creating the connection.
|
|
264
292
|
|
|
265
293
|
Returns:
|
|
266
|
-
Either a connection instance or an awaitable that resolves to a connection
|
|
267
|
-
depending on whether the configuration is sync or async.
|
|
294
|
+
Either a connection instance or an awaitable that resolves to a connection instance.
|
|
268
295
|
"""
|
|
269
296
|
config = self.get_config(name)
|
|
270
297
|
return config.create_connection()
|
|
271
298
|
|
|
299
|
+
@overload
|
|
300
|
+
def get_session(
|
|
301
|
+
self,
|
|
302
|
+
name: Union[
|
|
303
|
+
"type[NoPoolSyncConfig[ConnectionT, DriverT]]",
|
|
304
|
+
"type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
305
|
+
],
|
|
306
|
+
) -> "DriverT": ...
|
|
307
|
+
|
|
308
|
+
@overload
|
|
309
|
+
def get_session(
|
|
310
|
+
self,
|
|
311
|
+
name: Union[
|
|
312
|
+
"type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
|
|
313
|
+
"type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
314
|
+
],
|
|
315
|
+
) -> "Awaitable[DriverT]": ...
|
|
316
|
+
|
|
317
|
+
def get_session(
|
|
318
|
+
self,
|
|
319
|
+
name: Union[
|
|
320
|
+
"type[NoPoolSyncConfig[ConnectionT, DriverT]]",
|
|
321
|
+
"type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
|
|
322
|
+
"type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
323
|
+
"type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
324
|
+
],
|
|
325
|
+
) -> "Union[DriverT, Awaitable[DriverT]]":
|
|
326
|
+
"""Create and return a new database session from the specified configuration.
|
|
327
|
+
|
|
328
|
+
Args:
|
|
329
|
+
name: The configuration type to use for creating the session.
|
|
330
|
+
|
|
331
|
+
Returns:
|
|
332
|
+
Either a driver instance or an awaitable that resolves to a driver instance.
|
|
333
|
+
"""
|
|
334
|
+
config = self.get_config(name)
|
|
335
|
+
connection = self.get_connection(name)
|
|
336
|
+
if isinstance(connection, Awaitable):
|
|
337
|
+
|
|
338
|
+
async def _create_session() -> DriverT:
|
|
339
|
+
return cast("DriverT", config.driver_type(await connection)) # pyright: ignore
|
|
340
|
+
|
|
341
|
+
return _create_session()
|
|
342
|
+
return cast("DriverT", config.driver_type(connection)) # pyright: ignore
|
|
343
|
+
|
|
344
|
+
@overload
|
|
345
|
+
def provide_connection(
|
|
346
|
+
self,
|
|
347
|
+
name: Union[
|
|
348
|
+
"type[NoPoolSyncConfig[ConnectionT, DriverT]]",
|
|
349
|
+
"type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
350
|
+
],
|
|
351
|
+
*args: Any,
|
|
352
|
+
**kwargs: Any,
|
|
353
|
+
) -> "AbstractContextManager[ConnectionT]": ...
|
|
354
|
+
|
|
355
|
+
@overload
|
|
356
|
+
def provide_connection(
|
|
357
|
+
self,
|
|
358
|
+
name: Union[
|
|
359
|
+
"type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
|
|
360
|
+
"type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
361
|
+
],
|
|
362
|
+
*args: Any,
|
|
363
|
+
**kwargs: Any,
|
|
364
|
+
) -> "AbstractAsyncContextManager[ConnectionT]": ...
|
|
365
|
+
|
|
366
|
+
def provide_connection(
|
|
367
|
+
self,
|
|
368
|
+
name: Union[
|
|
369
|
+
"type[NoPoolSyncConfig[ConnectionT, DriverT]]",
|
|
370
|
+
"type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
|
|
371
|
+
"type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
372
|
+
"type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
373
|
+
],
|
|
374
|
+
*args: Any,
|
|
375
|
+
**kwargs: Any,
|
|
376
|
+
) -> "Union[AbstractContextManager[ConnectionT], AbstractAsyncContextManager[ConnectionT]]":
|
|
377
|
+
"""Create and provide a database connection from the specified configuration.
|
|
378
|
+
|
|
379
|
+
Args:
|
|
380
|
+
name: The configuration type to use for creating the connection.
|
|
381
|
+
*args: Positional arguments to pass to the configuration's provide_connection method.
|
|
382
|
+
**kwargs: Keyword arguments to pass to the configuration's provide_connection method.
|
|
383
|
+
|
|
384
|
+
Returns:
|
|
385
|
+
Either a synchronous or asynchronous context manager that provides a database connection.
|
|
386
|
+
"""
|
|
387
|
+
config = self.get_config(name)
|
|
388
|
+
return config.provide_connection(*args, **kwargs)
|
|
389
|
+
|
|
390
|
+
@overload
|
|
391
|
+
def provide_session(
|
|
392
|
+
self,
|
|
393
|
+
name: Union[
|
|
394
|
+
"type[NoPoolSyncConfig[ConnectionT, DriverT]]",
|
|
395
|
+
"type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
396
|
+
],
|
|
397
|
+
*args: Any,
|
|
398
|
+
**kwargs: Any,
|
|
399
|
+
) -> "AbstractContextManager[DriverT]": ...
|
|
400
|
+
|
|
401
|
+
@overload
|
|
402
|
+
def provide_session(
|
|
403
|
+
self,
|
|
404
|
+
name: Union[
|
|
405
|
+
"type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
|
|
406
|
+
"type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
407
|
+
],
|
|
408
|
+
*args: Any,
|
|
409
|
+
**kwargs: Any,
|
|
410
|
+
) -> "AbstractAsyncContextManager[DriverT]": ...
|
|
411
|
+
|
|
412
|
+
def provide_session(
|
|
413
|
+
self,
|
|
414
|
+
name: Union[
|
|
415
|
+
"type[NoPoolSyncConfig[ConnectionT, DriverT]]",
|
|
416
|
+
"type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
|
|
417
|
+
"type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
418
|
+
"type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
419
|
+
],
|
|
420
|
+
*args: Any,
|
|
421
|
+
**kwargs: Any,
|
|
422
|
+
) -> "Union[AbstractContextManager[DriverT], AbstractAsyncContextManager[DriverT]]":
|
|
423
|
+
"""Create and provide a database session from the specified configuration.
|
|
424
|
+
|
|
425
|
+
Args:
|
|
426
|
+
name: The configuration type to use for creating the session.
|
|
427
|
+
*args: Positional arguments to pass to the configuration's provide_session method.
|
|
428
|
+
**kwargs: Keyword arguments to pass to the configuration's provide_session method.
|
|
429
|
+
|
|
430
|
+
Returns:
|
|
431
|
+
Either a synchronous or asynchronous context manager that provides a database session.
|
|
432
|
+
"""
|
|
433
|
+
config = self.get_config(name)
|
|
434
|
+
return config.provide_session(*args, **kwargs)
|
|
435
|
+
|
|
272
436
|
@overload
|
|
273
437
|
def get_pool(
|
|
274
|
-
self, name: type[Union[NoPoolSyncConfig[ConnectionT, DriverT], NoPoolAsyncConfig[ConnectionT, DriverT]]]
|
|
275
|
-
) -> None: ... # pyright: ignore[reportInvalidTypeVarUse]
|
|
438
|
+
self, name: "type[Union[NoPoolSyncConfig[ConnectionT, DriverT], NoPoolAsyncConfig[ConnectionT, DriverT]]]"
|
|
439
|
+
) -> "None": ... # pyright: ignore[reportInvalidTypeVarUse]
|
|
276
440
|
|
|
277
441
|
@overload
|
|
278
|
-
def get_pool(self, name: type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]) -> type[PoolT]: ... # pyright: ignore[reportInvalidTypeVarUse]
|
|
442
|
+
def get_pool(self, name: "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]") -> "type[PoolT]": ... # pyright: ignore[reportInvalidTypeVarUse]
|
|
279
443
|
|
|
280
444
|
@overload
|
|
281
|
-
def get_pool(self, name: type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]) -> Awaitable[type[PoolT]]: ... # pyright: ignore[reportInvalidTypeVarUse]
|
|
445
|
+
def get_pool(self, name: "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]") -> "Awaitable[type[PoolT]]": ... # pyright: ignore[reportInvalidTypeVarUse]
|
|
282
446
|
|
|
283
447
|
def get_pool(
|
|
284
448
|
self,
|
|
285
449
|
name: Union[
|
|
286
|
-
type[NoPoolSyncConfig[ConnectionT, DriverT]],
|
|
287
|
-
type[NoPoolAsyncConfig[ConnectionT, DriverT]],
|
|
288
|
-
type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]],
|
|
289
|
-
type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]],
|
|
450
|
+
"type[NoPoolSyncConfig[ConnectionT, DriverT]]",
|
|
451
|
+
"type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
|
|
452
|
+
"type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
453
|
+
"type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
290
454
|
],
|
|
291
|
-
) -> Union[type[PoolT], Awaitable[type[PoolT]], None]:
|
|
455
|
+
) -> "Union[type[PoolT], Awaitable[type[PoolT]], None]":
|
|
292
456
|
"""Create and return a connection pool from the specified configuration.
|
|
293
457
|
|
|
294
458
|
Args:
|
|
@@ -303,15 +467,33 @@ class SQLSpec:
|
|
|
303
467
|
return cast("Union[type[PoolT], Awaitable[type[PoolT]]]", config.create_pool())
|
|
304
468
|
return None
|
|
305
469
|
|
|
470
|
+
@overload
|
|
471
|
+
def close_pool(
|
|
472
|
+
self,
|
|
473
|
+
name: Union[
|
|
474
|
+
"type[NoPoolSyncConfig[ConnectionT, DriverT]]",
|
|
475
|
+
"type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
476
|
+
],
|
|
477
|
+
) -> "None": ...
|
|
478
|
+
|
|
479
|
+
@overload
|
|
480
|
+
def close_pool(
|
|
481
|
+
self,
|
|
482
|
+
name: Union[
|
|
483
|
+
"type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
|
|
484
|
+
"type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
485
|
+
],
|
|
486
|
+
) -> "Awaitable[None]": ...
|
|
487
|
+
|
|
306
488
|
def close_pool(
|
|
307
489
|
self,
|
|
308
490
|
name: Union[
|
|
309
|
-
type[NoPoolSyncConfig[ConnectionT, DriverT]],
|
|
310
|
-
type[NoPoolAsyncConfig[ConnectionT, DriverT]],
|
|
311
|
-
type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]],
|
|
312
|
-
type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]],
|
|
491
|
+
"type[NoPoolSyncConfig[ConnectionT, DriverT]]",
|
|
492
|
+
"type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
|
|
493
|
+
"type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
494
|
+
"type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
|
|
313
495
|
],
|
|
314
|
-
) -> Optional[Awaitable[None]]:
|
|
496
|
+
) -> "Optional[Awaitable[None]]":
|
|
315
497
|
"""Close the connection pool for the specified configuration.
|
|
316
498
|
|
|
317
499
|
Args:
|
|
@@ -329,10 +511,12 @@ class SQLSpec:
|
|
|
329
511
|
class CommonDriverAttributes(Generic[ConnectionT]):
|
|
330
512
|
"""Common attributes and methods for driver adapters."""
|
|
331
513
|
|
|
332
|
-
|
|
333
|
-
"""The
|
|
514
|
+
dialect: str
|
|
515
|
+
"""The SQL dialect supported by the underlying database driver (e.g., 'postgres', 'mysql')."""
|
|
334
516
|
connection: ConnectionT
|
|
335
517
|
"""The connection to the underlying database."""
|
|
518
|
+
__supports_arrow__: ClassVar[bool] = False
|
|
519
|
+
"""Indicates if the driver supports Apache Arrow operations."""
|
|
336
520
|
|
|
337
521
|
def _connection(self, connection: "Optional[ConnectionT]" = None) -> "ConnectionT":
|
|
338
522
|
return connection if connection is not None else self.connection
|
|
@@ -355,100 +539,123 @@ class CommonDriverAttributes(Generic[ConnectionT]):
|
|
|
355
539
|
raise NotFoundError(msg)
|
|
356
540
|
return item_or_none
|
|
357
541
|
|
|
358
|
-
def
|
|
359
|
-
|
|
360
|
-
|
|
542
|
+
def _process_sql_params(
|
|
543
|
+
self, sql: str, parameters: "Optional[StatementParameterType]" = None, /, **kwargs: Any
|
|
544
|
+
) -> "tuple[str, Optional[Union[tuple[Any, ...], list[Any], dict[str, Any]]]]":
|
|
545
|
+
"""Process SQL query and parameters using SQLStatement for validation and formatting.
|
|
361
546
|
|
|
362
547
|
Args:
|
|
363
548
|
sql: The SQL query string.
|
|
549
|
+
parameters: Parameters for the query.
|
|
550
|
+
**kwargs: Additional keyword arguments to merge with parameters if parameters is a dict.
|
|
364
551
|
|
|
365
552
|
Returns:
|
|
366
|
-
|
|
553
|
+
A tuple containing the processed SQL query and parameters.
|
|
367
554
|
"""
|
|
368
|
-
|
|
555
|
+
# Instantiate SQLStatement with parameters and kwargs for internal merging
|
|
556
|
+
stmt = SQLStatement(sql=sql, parameters=parameters, dialect=self.dialect, kwargs=kwargs or None)
|
|
557
|
+
# Process uses the merged parameters internally
|
|
558
|
+
return stmt.process()
|
|
369
559
|
|
|
370
|
-
def _process_sql_params(
|
|
371
|
-
self, sql: str, parameters: "Optional[StatementParameterType]" = None
|
|
372
|
-
) -> "tuple[str, Optional[Union[tuple[Any, ...], list[Any], dict[str, Any]]]]":
|
|
373
|
-
"""Process SQL query and parameters for DB-API execution.
|
|
374
560
|
|
|
375
|
-
|
|
376
|
-
|
|
561
|
+
class SyncArrowBulkOperationsMixin(Generic[ConnectionT]):
|
|
562
|
+
"""Mixin for sync drivers supporting bulk Apache Arrow operations."""
|
|
563
|
+
|
|
564
|
+
__supports_arrow__: "ClassVar[bool]" = True
|
|
565
|
+
|
|
566
|
+
@abstractmethod
|
|
567
|
+
def select_arrow( # pyright: ignore[reportUnknownParameterType]
|
|
568
|
+
self,
|
|
569
|
+
sql: str,
|
|
570
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
571
|
+
/,
|
|
572
|
+
*,
|
|
573
|
+
connection: "Optional[ConnectionT]" = None,
|
|
574
|
+
**kwargs: Any,
|
|
575
|
+
) -> "ArrowTable": # pyright: ignore[reportUnknownReturnType]
|
|
576
|
+
"""Execute a SQL query and return results as an Apache Arrow Table.
|
|
377
577
|
|
|
378
578
|
Args:
|
|
379
579
|
sql: The SQL query string.
|
|
380
|
-
parameters:
|
|
580
|
+
parameters: Parameters for the query.
|
|
581
|
+
connection: Optional connection override.
|
|
582
|
+
**kwargs: Additional keyword arguments to merge with parameters if parameters is a dict.
|
|
381
583
|
|
|
382
584
|
Returns:
|
|
383
|
-
|
|
384
|
-
(always a tuple or None if the input was a dictionary, otherwise the original type).
|
|
385
|
-
|
|
386
|
-
Raises:
|
|
387
|
-
ValueError: If a named parameter in the SQL is not found in the dictionary
|
|
388
|
-
or if a parameter in the dictionary is not used in the SQL.
|
|
585
|
+
An Apache Arrow Table containing the query results.
|
|
389
586
|
"""
|
|
390
|
-
|
|
391
|
-
# If parameters are not a dict, or empty dict, assume positional/no params
|
|
392
|
-
# Let the underlying driver handle tuples/lists directly
|
|
393
|
-
return self._process_sql_statement(sql), parameters
|
|
394
|
-
|
|
395
|
-
processed_sql = ""
|
|
396
|
-
processed_params_list: list[Any] = []
|
|
397
|
-
last_end = 0
|
|
398
|
-
found_params: set[str] = set()
|
|
399
|
-
|
|
400
|
-
for match in PARAM_REGEX.finditer(sql):
|
|
401
|
-
if match.group("dquote") is not None or match.group("squote") is not None:
|
|
402
|
-
# Skip placeholders within quotes
|
|
403
|
-
continue
|
|
404
|
-
|
|
405
|
-
var_name = match.group("var_name")
|
|
406
|
-
if var_name is None: # Should not happen with the regex, but safeguard
|
|
407
|
-
continue
|
|
408
|
-
|
|
409
|
-
if var_name not in parameters:
|
|
410
|
-
msg = f"Named parameter ':{var_name}' found in SQL but not provided in parameters dictionary."
|
|
411
|
-
raise ValueError(msg)
|
|
412
|
-
|
|
413
|
-
# Append segment before the placeholder + the leading character + the driver's positional placeholder
|
|
414
|
-
# The match.start("var_name") -1 includes the character before the ':'
|
|
415
|
-
processed_sql += sql[last_end : match.start("var_name")] + self.param_style
|
|
416
|
-
processed_params_list.append(parameters[var_name])
|
|
417
|
-
found_params.add(var_name)
|
|
418
|
-
last_end = match.end("var_name")
|
|
419
|
-
|
|
420
|
-
# Append the rest of the SQL string
|
|
421
|
-
processed_sql += sql[last_end:]
|
|
422
|
-
|
|
423
|
-
# Check if all provided parameters were used
|
|
424
|
-
unused_params = set(parameters.keys()) - found_params
|
|
425
|
-
if unused_params:
|
|
426
|
-
msg = f"Parameters provided but not found in SQL: {unused_params}"
|
|
427
|
-
# Depending on desired strictness, this could be a warning or an error
|
|
428
|
-
# For now, let's raise an error for clarity
|
|
429
|
-
raise ValueError(msg)
|
|
430
|
-
|
|
431
|
-
processed_params = tuple(processed_params_list)
|
|
432
|
-
# Pass the processed SQL through the driver-specific processor if needed
|
|
433
|
-
final_sql = self._process_sql_statement(processed_sql)
|
|
434
|
-
return final_sql, processed_params
|
|
587
|
+
raise NotImplementedError
|
|
435
588
|
|
|
436
589
|
|
|
437
590
|
class SyncDriverAdapterProtocol(CommonDriverAttributes[ConnectionT], ABC, Generic[ConnectionT]):
|
|
438
|
-
connection: ConnectionT
|
|
591
|
+
connection: "ConnectionT"
|
|
439
592
|
|
|
440
|
-
def __init__(self, connection: ConnectionT) -> None:
|
|
593
|
+
def __init__(self, connection: "ConnectionT", **kwargs: Any) -> None:
|
|
441
594
|
self.connection = connection
|
|
442
595
|
|
|
596
|
+
@overload
|
|
443
597
|
@abstractmethod
|
|
444
598
|
def select(
|
|
445
599
|
self,
|
|
446
600
|
sql: str,
|
|
447
|
-
parameters: Optional[StatementParameterType] = None,
|
|
601
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
448
602
|
/,
|
|
449
|
-
|
|
603
|
+
*,
|
|
604
|
+
connection: "Optional[ConnectionT]" = None,
|
|
605
|
+
schema_type: None = None,
|
|
606
|
+
**kwargs: Any,
|
|
607
|
+
) -> "Sequence[dict[str, Any]]": ...
|
|
608
|
+
|
|
609
|
+
@overload
|
|
610
|
+
@abstractmethod
|
|
611
|
+
def select(
|
|
612
|
+
self,
|
|
613
|
+
sql: str,
|
|
614
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
615
|
+
/,
|
|
616
|
+
*,
|
|
617
|
+
connection: "Optional[ConnectionT]" = None,
|
|
618
|
+
schema_type: "type[ModelDTOT]",
|
|
619
|
+
**kwargs: Any,
|
|
620
|
+
) -> "Sequence[ModelDTOT]": ...
|
|
621
|
+
|
|
622
|
+
@abstractmethod
|
|
623
|
+
def select(
|
|
624
|
+
self,
|
|
625
|
+
sql: str,
|
|
626
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
627
|
+
/,
|
|
628
|
+
*,
|
|
629
|
+
connection: "Optional[ConnectionT]" = None,
|
|
450
630
|
schema_type: Optional[type[ModelDTOT]] = None,
|
|
451
|
-
|
|
631
|
+
**kwargs: Any,
|
|
632
|
+
) -> "Sequence[Union[ModelDTOT, dict[str, Any]]]": ...
|
|
633
|
+
|
|
634
|
+
@overload
|
|
635
|
+
@abstractmethod
|
|
636
|
+
def select_one(
|
|
637
|
+
self,
|
|
638
|
+
sql: str,
|
|
639
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
640
|
+
/,
|
|
641
|
+
*,
|
|
642
|
+
connection: "Optional[ConnectionT]" = None,
|
|
643
|
+
schema_type: None = None,
|
|
644
|
+
**kwargs: Any,
|
|
645
|
+
) -> "dict[str, Any]": ...
|
|
646
|
+
|
|
647
|
+
@overload
|
|
648
|
+
@abstractmethod
|
|
649
|
+
def select_one(
|
|
650
|
+
self,
|
|
651
|
+
sql: str,
|
|
652
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
653
|
+
/,
|
|
654
|
+
*,
|
|
655
|
+
connection: "Optional[ConnectionT]" = None,
|
|
656
|
+
schema_type: "type[ModelDTOT]",
|
|
657
|
+
**kwargs: Any,
|
|
658
|
+
) -> "ModelDTOT": ...
|
|
452
659
|
|
|
453
660
|
@abstractmethod
|
|
454
661
|
def select_one(
|
|
@@ -456,29 +663,113 @@ class SyncDriverAdapterProtocol(CommonDriverAttributes[ConnectionT], ABC, Generi
|
|
|
456
663
|
sql: str,
|
|
457
664
|
parameters: Optional[StatementParameterType] = None,
|
|
458
665
|
/,
|
|
666
|
+
*,
|
|
459
667
|
connection: Optional[ConnectionT] = None,
|
|
460
668
|
schema_type: Optional[type[ModelDTOT]] = None,
|
|
669
|
+
**kwargs: Any,
|
|
461
670
|
) -> "Union[ModelDTOT, dict[str, Any]]": ...
|
|
462
671
|
|
|
672
|
+
@overload
|
|
673
|
+
@abstractmethod
|
|
674
|
+
def select_one_or_none(
|
|
675
|
+
self,
|
|
676
|
+
sql: str,
|
|
677
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
678
|
+
/,
|
|
679
|
+
*,
|
|
680
|
+
connection: "Optional[ConnectionT]" = None,
|
|
681
|
+
schema_type: None = None,
|
|
682
|
+
**kwargs: Any,
|
|
683
|
+
) -> "Optional[dict[str, Any]]": ...
|
|
684
|
+
|
|
685
|
+
@overload
|
|
686
|
+
@abstractmethod
|
|
687
|
+
def select_one_or_none(
|
|
688
|
+
self,
|
|
689
|
+
sql: str,
|
|
690
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
691
|
+
/,
|
|
692
|
+
*,
|
|
693
|
+
connection: "Optional[ConnectionT]" = None,
|
|
694
|
+
schema_type: "type[ModelDTOT]",
|
|
695
|
+
**kwargs: Any,
|
|
696
|
+
) -> "Optional[ModelDTOT]": ...
|
|
697
|
+
|
|
463
698
|
@abstractmethod
|
|
464
699
|
def select_one_or_none(
|
|
465
700
|
self,
|
|
466
701
|
sql: str,
|
|
467
702
|
parameters: Optional[StatementParameterType] = None,
|
|
468
703
|
/,
|
|
704
|
+
*,
|
|
469
705
|
connection: Optional[ConnectionT] = None,
|
|
470
706
|
schema_type: Optional[type[ModelDTOT]] = None,
|
|
707
|
+
**kwargs: Any,
|
|
471
708
|
) -> "Optional[Union[ModelDTOT, dict[str, Any]]]": ...
|
|
472
709
|
|
|
710
|
+
@overload
|
|
711
|
+
@abstractmethod
|
|
712
|
+
def select_value(
|
|
713
|
+
self,
|
|
714
|
+
sql: str,
|
|
715
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
716
|
+
/,
|
|
717
|
+
*,
|
|
718
|
+
connection: "Optional[ConnectionT]" = None,
|
|
719
|
+
schema_type: None = None,
|
|
720
|
+
**kwargs: Any,
|
|
721
|
+
) -> "Any": ...
|
|
722
|
+
|
|
723
|
+
@overload
|
|
724
|
+
@abstractmethod
|
|
725
|
+
def select_value(
|
|
726
|
+
self,
|
|
727
|
+
sql: str,
|
|
728
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
729
|
+
/,
|
|
730
|
+
*,
|
|
731
|
+
connection: "Optional[ConnectionT]" = None,
|
|
732
|
+
schema_type: "type[T]",
|
|
733
|
+
**kwargs: Any,
|
|
734
|
+
) -> "T": ...
|
|
735
|
+
|
|
473
736
|
@abstractmethod
|
|
474
737
|
def select_value(
|
|
475
738
|
self,
|
|
476
739
|
sql: str,
|
|
477
740
|
parameters: Optional[StatementParameterType] = None,
|
|
478
741
|
/,
|
|
742
|
+
*,
|
|
479
743
|
connection: Optional[ConnectionT] = None,
|
|
480
744
|
schema_type: Optional[type[T]] = None,
|
|
481
|
-
|
|
745
|
+
**kwargs: Any,
|
|
746
|
+
) -> "Union[T, Any]": ...
|
|
747
|
+
|
|
748
|
+
@overload
|
|
749
|
+
@abstractmethod
|
|
750
|
+
def select_value_or_none(
|
|
751
|
+
self,
|
|
752
|
+
sql: str,
|
|
753
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
754
|
+
/,
|
|
755
|
+
*,
|
|
756
|
+
connection: "Optional[ConnectionT]" = None,
|
|
757
|
+
schema_type: None = None,
|
|
758
|
+
**kwargs: Any,
|
|
759
|
+
) -> "Optional[Any]": ...
|
|
760
|
+
|
|
761
|
+
@overload
|
|
762
|
+
@abstractmethod
|
|
763
|
+
def select_value_or_none(
|
|
764
|
+
self,
|
|
765
|
+
sql: str,
|
|
766
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
767
|
+
/,
|
|
768
|
+
*,
|
|
769
|
+
connection: "Optional[ConnectionT]" = None,
|
|
770
|
+
schema_type: "type[T]",
|
|
771
|
+
**kwargs: Any,
|
|
772
|
+
) -> "Optional[T]": ...
|
|
482
773
|
|
|
483
774
|
@abstractmethod
|
|
484
775
|
def select_value_or_none(
|
|
@@ -486,9 +777,11 @@ class SyncDriverAdapterProtocol(CommonDriverAttributes[ConnectionT], ABC, Generi
|
|
|
486
777
|
sql: str,
|
|
487
778
|
parameters: Optional[StatementParameterType] = None,
|
|
488
779
|
/,
|
|
780
|
+
*,
|
|
489
781
|
connection: Optional[ConnectionT] = None,
|
|
490
782
|
schema_type: Optional[type[T]] = None,
|
|
491
|
-
|
|
783
|
+
**kwargs: Any,
|
|
784
|
+
) -> "Optional[Union[T, Any]]": ...
|
|
492
785
|
|
|
493
786
|
@abstractmethod
|
|
494
787
|
def insert_update_delete(
|
|
@@ -496,18 +789,48 @@ class SyncDriverAdapterProtocol(CommonDriverAttributes[ConnectionT], ABC, Generi
|
|
|
496
789
|
sql: str,
|
|
497
790
|
parameters: Optional[StatementParameterType] = None,
|
|
498
791
|
/,
|
|
792
|
+
*,
|
|
499
793
|
connection: Optional[ConnectionT] = None,
|
|
794
|
+
**kwargs: Any,
|
|
500
795
|
) -> int: ...
|
|
501
796
|
|
|
797
|
+
@overload
|
|
798
|
+
@abstractmethod
|
|
799
|
+
def insert_update_delete_returning(
|
|
800
|
+
self,
|
|
801
|
+
sql: str,
|
|
802
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
803
|
+
/,
|
|
804
|
+
*,
|
|
805
|
+
connection: "Optional[ConnectionT]" = None,
|
|
806
|
+
schema_type: None = None,
|
|
807
|
+
**kwargs: Any,
|
|
808
|
+
) -> "dict[str, Any]": ...
|
|
809
|
+
|
|
810
|
+
@overload
|
|
811
|
+
@abstractmethod
|
|
812
|
+
def insert_update_delete_returning(
|
|
813
|
+
self,
|
|
814
|
+
sql: str,
|
|
815
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
816
|
+
/,
|
|
817
|
+
*,
|
|
818
|
+
connection: "Optional[ConnectionT]" = None,
|
|
819
|
+
schema_type: "type[ModelDTOT]",
|
|
820
|
+
**kwargs: Any,
|
|
821
|
+
) -> "ModelDTOT": ...
|
|
822
|
+
|
|
502
823
|
@abstractmethod
|
|
503
824
|
def insert_update_delete_returning(
|
|
504
825
|
self,
|
|
505
826
|
sql: str,
|
|
506
827
|
parameters: Optional[StatementParameterType] = None,
|
|
507
828
|
/,
|
|
829
|
+
*,
|
|
508
830
|
connection: Optional[ConnectionT] = None,
|
|
509
831
|
schema_type: Optional[type[ModelDTOT]] = None,
|
|
510
|
-
|
|
832
|
+
**kwargs: Any,
|
|
833
|
+
) -> "Union[ModelDTOT, dict[str, Any]]": ...
|
|
511
834
|
|
|
512
835
|
@abstractmethod
|
|
513
836
|
def execute_script(
|
|
@@ -515,92 +838,295 @@ class SyncDriverAdapterProtocol(CommonDriverAttributes[ConnectionT], ABC, Generi
|
|
|
515
838
|
sql: str,
|
|
516
839
|
parameters: Optional[StatementParameterType] = None,
|
|
517
840
|
/,
|
|
841
|
+
*,
|
|
518
842
|
connection: Optional[ConnectionT] = None,
|
|
843
|
+
**kwargs: Any,
|
|
519
844
|
) -> str: ...
|
|
520
845
|
|
|
521
846
|
|
|
847
|
+
class AsyncArrowBulkOperationsMixin(Generic[ConnectionT]):
|
|
848
|
+
"""Mixin for async drivers supporting bulk Apache Arrow operations."""
|
|
849
|
+
|
|
850
|
+
__supports_arrow__: "ClassVar[bool]" = True
|
|
851
|
+
|
|
852
|
+
@abstractmethod
|
|
853
|
+
async def select_arrow( # pyright: ignore[reportUnknownParameterType]
|
|
854
|
+
self,
|
|
855
|
+
sql: str,
|
|
856
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
857
|
+
/,
|
|
858
|
+
*,
|
|
859
|
+
connection: "Optional[ConnectionT]" = None,
|
|
860
|
+
**kwargs: Any,
|
|
861
|
+
) -> "ArrowTable": # pyright: ignore[reportUnknownReturnType]
|
|
862
|
+
"""Execute a SQL query and return results as an Apache Arrow Table.
|
|
863
|
+
|
|
864
|
+
Args:
|
|
865
|
+
sql: The SQL query string.
|
|
866
|
+
parameters: Parameters for the query.
|
|
867
|
+
connection: Optional connection override.
|
|
868
|
+
**kwargs: Additional keyword arguments to merge with parameters if parameters is a dict.
|
|
869
|
+
|
|
870
|
+
Returns:
|
|
871
|
+
An Apache Arrow Table containing the query results.
|
|
872
|
+
"""
|
|
873
|
+
raise NotImplementedError
|
|
874
|
+
|
|
875
|
+
|
|
522
876
|
class AsyncDriverAdapterProtocol(CommonDriverAttributes[ConnectionT], ABC, Generic[ConnectionT]):
|
|
523
|
-
connection: ConnectionT
|
|
877
|
+
connection: "ConnectionT"
|
|
524
878
|
|
|
525
|
-
def __init__(self, connection: ConnectionT) -> None:
|
|
879
|
+
def __init__(self, connection: "ConnectionT") -> None:
|
|
526
880
|
self.connection = connection
|
|
527
881
|
|
|
882
|
+
@overload
|
|
528
883
|
@abstractmethod
|
|
529
884
|
async def select(
|
|
530
885
|
self,
|
|
531
886
|
sql: str,
|
|
532
|
-
parameters: Optional[StatementParameterType] = None,
|
|
887
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
533
888
|
/,
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
889
|
+
*,
|
|
890
|
+
connection: "Optional[ConnectionT]" = None,
|
|
891
|
+
schema_type: None = None,
|
|
892
|
+
**kwargs: Any,
|
|
893
|
+
) -> "Sequence[dict[str, Any]]": ...
|
|
894
|
+
|
|
895
|
+
@overload
|
|
896
|
+
@abstractmethod
|
|
897
|
+
async def select(
|
|
898
|
+
self,
|
|
899
|
+
sql: str,
|
|
900
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
901
|
+
/,
|
|
902
|
+
*,
|
|
903
|
+
connection: "Optional[ConnectionT]" = None,
|
|
904
|
+
schema_type: "type[ModelDTOT]",
|
|
905
|
+
**kwargs: Any,
|
|
906
|
+
) -> "Sequence[ModelDTOT]": ...
|
|
537
907
|
|
|
908
|
+
@abstractmethod
|
|
909
|
+
async def select(
|
|
910
|
+
self,
|
|
911
|
+
sql: str,
|
|
912
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
913
|
+
/,
|
|
914
|
+
*,
|
|
915
|
+
connection: "Optional[ConnectionT]" = None,
|
|
916
|
+
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
917
|
+
**kwargs: Any,
|
|
918
|
+
) -> "Sequence[Union[ModelDTOT, dict[str, Any]]]": ...
|
|
919
|
+
|
|
920
|
+
@overload
|
|
538
921
|
@abstractmethod
|
|
539
922
|
async def select_one(
|
|
540
923
|
self,
|
|
541
924
|
sql: str,
|
|
542
|
-
parameters: Optional[StatementParameterType] = None,
|
|
925
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
543
926
|
/,
|
|
544
|
-
|
|
545
|
-
|
|
927
|
+
*,
|
|
928
|
+
connection: "Optional[ConnectionT]" = None,
|
|
929
|
+
schema_type: None = None,
|
|
930
|
+
**kwargs: Any,
|
|
931
|
+
) -> "dict[str, Any]": ...
|
|
932
|
+
|
|
933
|
+
@overload
|
|
934
|
+
@abstractmethod
|
|
935
|
+
async def select_one(
|
|
936
|
+
self,
|
|
937
|
+
sql: str,
|
|
938
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
939
|
+
/,
|
|
940
|
+
*,
|
|
941
|
+
connection: "Optional[ConnectionT]" = None,
|
|
942
|
+
schema_type: "type[ModelDTOT]",
|
|
943
|
+
**kwargs: Any,
|
|
944
|
+
) -> "ModelDTOT": ...
|
|
945
|
+
|
|
946
|
+
@abstractmethod
|
|
947
|
+
async def select_one(
|
|
948
|
+
self,
|
|
949
|
+
sql: str,
|
|
950
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
951
|
+
/,
|
|
952
|
+
*,
|
|
953
|
+
connection: "Optional[ConnectionT]" = None,
|
|
954
|
+
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
955
|
+
**kwargs: Any,
|
|
546
956
|
) -> "Union[ModelDTOT, dict[str, Any]]": ...
|
|
547
957
|
|
|
958
|
+
@overload
|
|
548
959
|
@abstractmethod
|
|
549
960
|
async def select_one_or_none(
|
|
550
961
|
self,
|
|
551
962
|
sql: str,
|
|
552
|
-
parameters: Optional[StatementParameterType] = None,
|
|
963
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
553
964
|
/,
|
|
554
|
-
|
|
555
|
-
|
|
965
|
+
*,
|
|
966
|
+
connection: "Optional[ConnectionT]" = None,
|
|
967
|
+
schema_type: None = None,
|
|
968
|
+
**kwargs: Any,
|
|
969
|
+
) -> "Optional[dict[str, Any]]": ...
|
|
970
|
+
|
|
971
|
+
@overload
|
|
972
|
+
@abstractmethod
|
|
973
|
+
async def select_one_or_none(
|
|
974
|
+
self,
|
|
975
|
+
sql: str,
|
|
976
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
977
|
+
/,
|
|
978
|
+
*,
|
|
979
|
+
connection: "Optional[ConnectionT]" = None,
|
|
980
|
+
schema_type: "type[ModelDTOT]",
|
|
981
|
+
**kwargs: Any,
|
|
982
|
+
) -> "Optional[ModelDTOT]": ...
|
|
983
|
+
|
|
984
|
+
@abstractmethod
|
|
985
|
+
async def select_one_or_none(
|
|
986
|
+
self,
|
|
987
|
+
sql: str,
|
|
988
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
989
|
+
/,
|
|
990
|
+
*,
|
|
991
|
+
connection: "Optional[ConnectionT]" = None,
|
|
992
|
+
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
993
|
+
**kwargs: Any,
|
|
556
994
|
) -> "Optional[Union[ModelDTOT, dict[str, Any]]]": ...
|
|
557
995
|
|
|
996
|
+
@overload
|
|
558
997
|
@abstractmethod
|
|
559
998
|
async def select_value(
|
|
560
999
|
self,
|
|
561
1000
|
sql: str,
|
|
562
|
-
parameters: Optional[StatementParameterType] = None,
|
|
1001
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
563
1002
|
/,
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
1003
|
+
*,
|
|
1004
|
+
connection: "Optional[ConnectionT]" = None,
|
|
1005
|
+
schema_type: None = None,
|
|
1006
|
+
**kwargs: Any,
|
|
1007
|
+
) -> "Any": ...
|
|
567
1008
|
|
|
1009
|
+
@overload
|
|
1010
|
+
@abstractmethod
|
|
1011
|
+
async def select_value(
|
|
1012
|
+
self,
|
|
1013
|
+
sql: str,
|
|
1014
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
1015
|
+
/,
|
|
1016
|
+
*,
|
|
1017
|
+
connection: "Optional[ConnectionT]" = None,
|
|
1018
|
+
schema_type: "type[T]",
|
|
1019
|
+
**kwargs: Any,
|
|
1020
|
+
) -> "T": ...
|
|
1021
|
+
|
|
1022
|
+
@abstractmethod
|
|
1023
|
+
async def select_value(
|
|
1024
|
+
self,
|
|
1025
|
+
sql: str,
|
|
1026
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
1027
|
+
/,
|
|
1028
|
+
*,
|
|
1029
|
+
connection: "Optional[ConnectionT]" = None,
|
|
1030
|
+
schema_type: "Optional[type[T]]" = None,
|
|
1031
|
+
**kwargs: Any,
|
|
1032
|
+
) -> "Union[T, Any]": ...
|
|
1033
|
+
|
|
1034
|
+
@overload
|
|
568
1035
|
@abstractmethod
|
|
569
1036
|
async def select_value_or_none(
|
|
570
1037
|
self,
|
|
571
1038
|
sql: str,
|
|
572
|
-
parameters: Optional[StatementParameterType] = None,
|
|
1039
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
573
1040
|
/,
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
1041
|
+
*,
|
|
1042
|
+
connection: "Optional[ConnectionT]" = None,
|
|
1043
|
+
schema_type: None = None,
|
|
1044
|
+
**kwargs: Any,
|
|
1045
|
+
) -> "Optional[Any]": ...
|
|
1046
|
+
|
|
1047
|
+
@overload
|
|
1048
|
+
@abstractmethod
|
|
1049
|
+
async def select_value_or_none(
|
|
1050
|
+
self,
|
|
1051
|
+
sql: str,
|
|
1052
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
1053
|
+
/,
|
|
1054
|
+
*,
|
|
1055
|
+
connection: "Optional[ConnectionT]" = None,
|
|
1056
|
+
schema_type: "type[T]",
|
|
1057
|
+
**kwargs: Any,
|
|
1058
|
+
) -> "Optional[T]": ...
|
|
1059
|
+
|
|
1060
|
+
@abstractmethod
|
|
1061
|
+
async def select_value_or_none(
|
|
1062
|
+
self,
|
|
1063
|
+
sql: str,
|
|
1064
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
1065
|
+
/,
|
|
1066
|
+
*,
|
|
1067
|
+
connection: "Optional[ConnectionT]" = None,
|
|
1068
|
+
schema_type: "Optional[type[T]]" = None,
|
|
1069
|
+
**kwargs: Any,
|
|
1070
|
+
) -> "Optional[Union[T, Any]]": ...
|
|
577
1071
|
|
|
578
1072
|
@abstractmethod
|
|
579
1073
|
async def insert_update_delete(
|
|
580
1074
|
self,
|
|
581
1075
|
sql: str,
|
|
582
|
-
parameters: Optional[StatementParameterType] = None,
|
|
1076
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
583
1077
|
/,
|
|
584
|
-
|
|
1078
|
+
*,
|
|
1079
|
+
connection: "Optional[ConnectionT]" = None,
|
|
1080
|
+
**kwargs: Any,
|
|
585
1081
|
) -> int: ...
|
|
586
1082
|
|
|
1083
|
+
@overload
|
|
587
1084
|
@abstractmethod
|
|
588
1085
|
async def insert_update_delete_returning(
|
|
589
1086
|
self,
|
|
590
1087
|
sql: str,
|
|
591
|
-
parameters: Optional[StatementParameterType] = None,
|
|
1088
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
592
1089
|
/,
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
1090
|
+
*,
|
|
1091
|
+
connection: "Optional[ConnectionT]" = None,
|
|
1092
|
+
schema_type: None = None,
|
|
1093
|
+
**kwargs: Any,
|
|
1094
|
+
) -> "dict[str, Any]": ...
|
|
1095
|
+
|
|
1096
|
+
@overload
|
|
1097
|
+
@abstractmethod
|
|
1098
|
+
async def insert_update_delete_returning(
|
|
1099
|
+
self,
|
|
1100
|
+
sql: str,
|
|
1101
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
1102
|
+
/,
|
|
1103
|
+
*,
|
|
1104
|
+
connection: "Optional[ConnectionT]" = None,
|
|
1105
|
+
schema_type: "type[ModelDTOT]",
|
|
1106
|
+
**kwargs: Any,
|
|
1107
|
+
) -> "ModelDTOT": ...
|
|
1108
|
+
|
|
1109
|
+
@abstractmethod
|
|
1110
|
+
async def insert_update_delete_returning(
|
|
1111
|
+
self,
|
|
1112
|
+
sql: str,
|
|
1113
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
1114
|
+
/,
|
|
1115
|
+
*,
|
|
1116
|
+
connection: "Optional[ConnectionT]" = None,
|
|
1117
|
+
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
1118
|
+
**kwargs: Any,
|
|
1119
|
+
) -> "Union[ModelDTOT, dict[str, Any]]": ...
|
|
596
1120
|
|
|
597
1121
|
@abstractmethod
|
|
598
1122
|
async def execute_script(
|
|
599
1123
|
self,
|
|
600
1124
|
sql: str,
|
|
601
|
-
parameters: Optional[StatementParameterType] = None,
|
|
1125
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
602
1126
|
/,
|
|
603
|
-
|
|
1127
|
+
*,
|
|
1128
|
+
connection: "Optional[ConnectionT]" = None,
|
|
1129
|
+
**kwargs: Any,
|
|
604
1130
|
) -> str: ...
|
|
605
1131
|
|
|
606
1132
|
|