sqlspec 0.11.1__py3-none-any.whl → 0.12.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.

Files changed (155) hide show
  1. sqlspec/__init__.py +16 -3
  2. sqlspec/_serialization.py +3 -10
  3. sqlspec/_sql.py +1147 -0
  4. sqlspec/_typing.py +343 -41
  5. sqlspec/adapters/adbc/__init__.py +2 -6
  6. sqlspec/adapters/adbc/config.py +474 -149
  7. sqlspec/adapters/adbc/driver.py +330 -621
  8. sqlspec/adapters/aiosqlite/__init__.py +2 -6
  9. sqlspec/adapters/aiosqlite/config.py +143 -57
  10. sqlspec/adapters/aiosqlite/driver.py +269 -431
  11. sqlspec/adapters/asyncmy/__init__.py +3 -8
  12. sqlspec/adapters/asyncmy/config.py +247 -202
  13. sqlspec/adapters/asyncmy/driver.py +218 -436
  14. sqlspec/adapters/asyncpg/__init__.py +4 -7
  15. sqlspec/adapters/asyncpg/config.py +329 -176
  16. sqlspec/adapters/asyncpg/driver.py +417 -487
  17. sqlspec/adapters/bigquery/__init__.py +2 -2
  18. sqlspec/adapters/bigquery/config.py +407 -0
  19. sqlspec/adapters/bigquery/driver.py +600 -553
  20. sqlspec/adapters/duckdb/__init__.py +4 -1
  21. sqlspec/adapters/duckdb/config.py +432 -321
  22. sqlspec/adapters/duckdb/driver.py +392 -406
  23. sqlspec/adapters/oracledb/__init__.py +3 -8
  24. sqlspec/adapters/oracledb/config.py +625 -0
  25. sqlspec/adapters/oracledb/driver.py +548 -921
  26. sqlspec/adapters/psqlpy/__init__.py +4 -7
  27. sqlspec/adapters/psqlpy/config.py +372 -203
  28. sqlspec/adapters/psqlpy/driver.py +197 -533
  29. sqlspec/adapters/psycopg/__init__.py +3 -8
  30. sqlspec/adapters/psycopg/config.py +725 -0
  31. sqlspec/adapters/psycopg/driver.py +734 -694
  32. sqlspec/adapters/sqlite/__init__.py +2 -6
  33. sqlspec/adapters/sqlite/config.py +146 -81
  34. sqlspec/adapters/sqlite/driver.py +242 -405
  35. sqlspec/base.py +220 -784
  36. sqlspec/config.py +354 -0
  37. sqlspec/driver/__init__.py +22 -0
  38. sqlspec/driver/_async.py +252 -0
  39. sqlspec/driver/_common.py +338 -0
  40. sqlspec/driver/_sync.py +261 -0
  41. sqlspec/driver/mixins/__init__.py +17 -0
  42. sqlspec/driver/mixins/_pipeline.py +523 -0
  43. sqlspec/driver/mixins/_result_utils.py +122 -0
  44. sqlspec/driver/mixins/_sql_translator.py +35 -0
  45. sqlspec/driver/mixins/_storage.py +993 -0
  46. sqlspec/driver/mixins/_type_coercion.py +131 -0
  47. sqlspec/exceptions.py +299 -7
  48. sqlspec/extensions/aiosql/__init__.py +10 -0
  49. sqlspec/extensions/aiosql/adapter.py +474 -0
  50. sqlspec/extensions/litestar/__init__.py +1 -6
  51. sqlspec/extensions/litestar/_utils.py +1 -5
  52. sqlspec/extensions/litestar/config.py +5 -6
  53. sqlspec/extensions/litestar/handlers.py +13 -12
  54. sqlspec/extensions/litestar/plugin.py +22 -24
  55. sqlspec/extensions/litestar/providers.py +37 -55
  56. sqlspec/loader.py +528 -0
  57. sqlspec/service/__init__.py +3 -0
  58. sqlspec/service/base.py +24 -0
  59. sqlspec/service/pagination.py +26 -0
  60. sqlspec/statement/__init__.py +21 -0
  61. sqlspec/statement/builder/__init__.py +54 -0
  62. sqlspec/statement/builder/_ddl_utils.py +119 -0
  63. sqlspec/statement/builder/_parsing_utils.py +135 -0
  64. sqlspec/statement/builder/base.py +328 -0
  65. sqlspec/statement/builder/ddl.py +1379 -0
  66. sqlspec/statement/builder/delete.py +80 -0
  67. sqlspec/statement/builder/insert.py +274 -0
  68. sqlspec/statement/builder/merge.py +95 -0
  69. sqlspec/statement/builder/mixins/__init__.py +65 -0
  70. sqlspec/statement/builder/mixins/_aggregate_functions.py +151 -0
  71. sqlspec/statement/builder/mixins/_case_builder.py +91 -0
  72. sqlspec/statement/builder/mixins/_common_table_expr.py +91 -0
  73. sqlspec/statement/builder/mixins/_delete_from.py +34 -0
  74. sqlspec/statement/builder/mixins/_from.py +61 -0
  75. sqlspec/statement/builder/mixins/_group_by.py +119 -0
  76. sqlspec/statement/builder/mixins/_having.py +35 -0
  77. sqlspec/statement/builder/mixins/_insert_from_select.py +48 -0
  78. sqlspec/statement/builder/mixins/_insert_into.py +36 -0
  79. sqlspec/statement/builder/mixins/_insert_values.py +69 -0
  80. sqlspec/statement/builder/mixins/_join.py +110 -0
  81. sqlspec/statement/builder/mixins/_limit_offset.py +53 -0
  82. sqlspec/statement/builder/mixins/_merge_clauses.py +405 -0
  83. sqlspec/statement/builder/mixins/_order_by.py +46 -0
  84. sqlspec/statement/builder/mixins/_pivot.py +82 -0
  85. sqlspec/statement/builder/mixins/_returning.py +37 -0
  86. sqlspec/statement/builder/mixins/_select_columns.py +60 -0
  87. sqlspec/statement/builder/mixins/_set_ops.py +122 -0
  88. sqlspec/statement/builder/mixins/_unpivot.py +80 -0
  89. sqlspec/statement/builder/mixins/_update_from.py +54 -0
  90. sqlspec/statement/builder/mixins/_update_set.py +91 -0
  91. sqlspec/statement/builder/mixins/_update_table.py +29 -0
  92. sqlspec/statement/builder/mixins/_where.py +374 -0
  93. sqlspec/statement/builder/mixins/_window_functions.py +86 -0
  94. sqlspec/statement/builder/protocols.py +20 -0
  95. sqlspec/statement/builder/select.py +206 -0
  96. sqlspec/statement/builder/update.py +178 -0
  97. sqlspec/statement/filters.py +571 -0
  98. sqlspec/statement/parameters.py +736 -0
  99. sqlspec/statement/pipelines/__init__.py +67 -0
  100. sqlspec/statement/pipelines/analyzers/__init__.py +9 -0
  101. sqlspec/statement/pipelines/analyzers/_analyzer.py +649 -0
  102. sqlspec/statement/pipelines/base.py +315 -0
  103. sqlspec/statement/pipelines/context.py +119 -0
  104. sqlspec/statement/pipelines/result_types.py +41 -0
  105. sqlspec/statement/pipelines/transformers/__init__.py +8 -0
  106. sqlspec/statement/pipelines/transformers/_expression_simplifier.py +256 -0
  107. sqlspec/statement/pipelines/transformers/_literal_parameterizer.py +623 -0
  108. sqlspec/statement/pipelines/transformers/_remove_comments.py +66 -0
  109. sqlspec/statement/pipelines/transformers/_remove_hints.py +81 -0
  110. sqlspec/statement/pipelines/validators/__init__.py +23 -0
  111. sqlspec/statement/pipelines/validators/_dml_safety.py +275 -0
  112. sqlspec/statement/pipelines/validators/_parameter_style.py +297 -0
  113. sqlspec/statement/pipelines/validators/_performance.py +703 -0
  114. sqlspec/statement/pipelines/validators/_security.py +990 -0
  115. sqlspec/statement/pipelines/validators/base.py +67 -0
  116. sqlspec/statement/result.py +527 -0
  117. sqlspec/statement/splitter.py +701 -0
  118. sqlspec/statement/sql.py +1198 -0
  119. sqlspec/storage/__init__.py +15 -0
  120. sqlspec/storage/backends/__init__.py +0 -0
  121. sqlspec/storage/backends/base.py +166 -0
  122. sqlspec/storage/backends/fsspec.py +315 -0
  123. sqlspec/storage/backends/obstore.py +464 -0
  124. sqlspec/storage/protocol.py +170 -0
  125. sqlspec/storage/registry.py +315 -0
  126. sqlspec/typing.py +157 -36
  127. sqlspec/utils/correlation.py +155 -0
  128. sqlspec/utils/deprecation.py +3 -6
  129. sqlspec/utils/fixtures.py +6 -11
  130. sqlspec/utils/logging.py +135 -0
  131. sqlspec/utils/module_loader.py +45 -43
  132. sqlspec/utils/serializers.py +4 -0
  133. sqlspec/utils/singleton.py +6 -8
  134. sqlspec/utils/sync_tools.py +15 -27
  135. sqlspec/utils/text.py +58 -26
  136. {sqlspec-0.11.1.dist-info → sqlspec-0.12.1.dist-info}/METADATA +97 -26
  137. sqlspec-0.12.1.dist-info/RECORD +145 -0
  138. sqlspec/adapters/bigquery/config/__init__.py +0 -3
  139. sqlspec/adapters/bigquery/config/_common.py +0 -40
  140. sqlspec/adapters/bigquery/config/_sync.py +0 -87
  141. sqlspec/adapters/oracledb/config/__init__.py +0 -9
  142. sqlspec/adapters/oracledb/config/_asyncio.py +0 -186
  143. sqlspec/adapters/oracledb/config/_common.py +0 -131
  144. sqlspec/adapters/oracledb/config/_sync.py +0 -186
  145. sqlspec/adapters/psycopg/config/__init__.py +0 -19
  146. sqlspec/adapters/psycopg/config/_async.py +0 -169
  147. sqlspec/adapters/psycopg/config/_common.py +0 -56
  148. sqlspec/adapters/psycopg/config/_sync.py +0 -168
  149. sqlspec/filters.py +0 -331
  150. sqlspec/mixins.py +0 -305
  151. sqlspec/statement.py +0 -378
  152. sqlspec-0.11.1.dist-info/RECORD +0 -69
  153. {sqlspec-0.11.1.dist-info → sqlspec-0.12.1.dist-info}/WHEEL +0 -0
  154. {sqlspec-0.11.1.dist-info → sqlspec-0.12.1.dist-info}/licenses/LICENSE +0 -0
  155. {sqlspec-0.11.1.dist-info → sqlspec-0.12.1.dist-info}/licenses/NOTICE +0 -0
sqlspec/base.py CHANGED
@@ -1,196 +1,29 @@
1
- # ruff: noqa: PLR6301
1
+ import asyncio
2
2
  import atexit
3
- import contextlib
4
- import re
5
- from abc import ABC, abstractmethod
6
- from collections.abc import Awaitable, Sequence
7
- from dataclasses import dataclass, field
8
- from typing import (
9
- TYPE_CHECKING,
10
- Annotated,
11
- Any,
12
- ClassVar,
13
- Generic,
14
- Optional,
15
- TypeVar,
16
- Union,
17
- cast,
18
- overload,
3
+ from collections.abc import Awaitable, Coroutine
4
+ from typing import TYPE_CHECKING, Any, Optional, Union, cast, overload
5
+
6
+ from sqlspec.config import (
7
+ AsyncConfigT,
8
+ AsyncDatabaseConfig,
9
+ DatabaseConfigProtocol,
10
+ DriverT,
11
+ NoPoolAsyncConfig,
12
+ NoPoolSyncConfig,
13
+ SyncConfigT,
14
+ SyncDatabaseConfig,
19
15
  )
20
-
21
- from sqlspec.exceptions import NotFoundError
22
- from sqlspec.statement import SQLStatement
23
- from sqlspec.typing import ConnectionT, ModelDTOT, PoolT, StatementParameterType, T
24
- from sqlspec.utils.sync_tools import ensure_async_
16
+ from sqlspec.utils.logging import get_logger
25
17
 
26
18
  if TYPE_CHECKING:
27
19
  from contextlib import AbstractAsyncContextManager, AbstractContextManager
28
20
 
29
- from sqlspec.filters import StatementFilter
30
-
31
-
32
- __all__ = (
33
- "AsyncDatabaseConfig",
34
- "AsyncDriverAdapterProtocol",
35
- "CommonDriverAttributes",
36
- "DatabaseConfigProtocol",
37
- "GenericPoolConfig",
38
- "NoPoolAsyncConfig",
39
- "NoPoolSyncConfig",
40
- "SQLSpec",
41
- "SQLStatement",
42
- "SyncDatabaseConfig",
43
- "SyncDriverAdapterProtocol",
44
- )
45
-
46
- AsyncConfigT = TypeVar("AsyncConfigT", bound="Union[AsyncDatabaseConfig[Any, Any, Any], NoPoolAsyncConfig[Any, Any]]")
47
- SyncConfigT = TypeVar("SyncConfigT", bound="Union[SyncDatabaseConfig[Any, Any, Any], NoPoolSyncConfig[Any, Any]]")
48
- ConfigT = TypeVar(
49
- "ConfigT",
50
- bound="Union[Union[AsyncDatabaseConfig[Any, Any, Any], NoPoolAsyncConfig[Any, Any]], SyncDatabaseConfig[Any, Any, Any], NoPoolSyncConfig[Any, Any]]",
51
- )
52
- DriverT = TypeVar("DriverT", bound="Union[SyncDriverAdapterProtocol[Any], AsyncDriverAdapterProtocol[Any]]")
53
- # Regex to find :param or %(param)s style placeholders, skipping those inside quotes
54
- PARAM_REGEX = re.compile(
55
- r"""
56
- (?P<dquote>"([^"]|\\")*") | # Double-quoted strings
57
- (?P<squote>'([^']|\\')*') | # Single-quoted strings
58
- : (?P<var_name_colon>[a-zA-Z_][a-zA-Z0-9_]*) | # :var_name
59
- % \( (?P<var_name_perc>[a-zA-Z_][a-zA-Z0-9_]*) \) s # %(var_name)s
60
- """,
61
- re.VERBOSE,
62
- )
63
-
64
-
65
- @dataclass
66
- class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
67
- """Protocol defining the interface for database configurations."""
68
-
69
- connection_type: "type[ConnectionT]" = field(init=False)
70
- driver_type: "type[DriverT]" = field(init=False)
71
- pool_instance: "Optional[PoolT]" = field(default=None)
72
- __is_async__: "ClassVar[bool]" = False
73
- __supports_connection_pooling__: "ClassVar[bool]" = False
74
-
75
- def __hash__(self) -> int:
76
- return id(self)
77
-
78
- @abstractmethod
79
- def create_connection(self) -> "Union[ConnectionT, Awaitable[ConnectionT]]":
80
- """Create and return a new database connection."""
81
- raise NotImplementedError
82
-
83
- @abstractmethod
84
- def provide_connection(
85
- self,
86
- *args: Any,
87
- **kwargs: Any,
88
- ) -> "Union[AbstractContextManager[ConnectionT], AbstractAsyncContextManager[ConnectionT]]":
89
- """Provide a database connection context manager."""
90
- raise NotImplementedError
91
-
92
- @abstractmethod
93
- def provide_session(
94
- self,
95
- *args: Any,
96
- **kwargs: Any,
97
- ) -> "Union[AbstractContextManager[DriverT], AbstractAsyncContextManager[DriverT]]":
98
- """Provide a database session context manager."""
99
- raise NotImplementedError
100
-
101
- @property
102
- @abstractmethod
103
- def connection_config_dict(self) -> "dict[str, Any]":
104
- """Return the connection configuration as a dict."""
105
- raise NotImplementedError
106
-
107
- @abstractmethod
108
- def create_pool(self) -> "Union[PoolT, Awaitable[PoolT]]":
109
- """Create and return connection pool."""
110
- raise NotImplementedError
111
-
112
- @abstractmethod
113
- def close_pool(self) -> "Optional[Awaitable[None]]":
114
- """Terminate the connection pool."""
115
- raise NotImplementedError
116
-
117
- @abstractmethod
118
- def provide_pool(
119
- self,
120
- *args: Any,
121
- **kwargs: Any,
122
- ) -> "Union[PoolT, Awaitable[PoolT], AbstractContextManager[PoolT], AbstractAsyncContextManager[PoolT]]":
123
- """Provide pool instance."""
124
- raise NotImplementedError
125
-
126
- @property
127
- def is_async(self) -> bool:
128
- """Return whether the configuration is for an async database."""
129
- return self.__is_async__
130
-
131
- @property
132
- def support_connection_pooling(self) -> bool:
133
- """Return whether the configuration supports connection pooling."""
134
- return self.__supports_connection_pooling__
135
-
136
-
137
- class NoPoolSyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
138
- """Base class for a sync database configurations that do not implement a pool."""
139
-
140
- __is_async__ = False
141
- __supports_connection_pooling__ = False
142
- pool_instance: None = None
143
-
144
- def create_pool(self) -> None:
145
- """This database backend has not implemented the pooling configurations."""
146
- return
21
+ from sqlspec.typing import ConnectionT, PoolT
147
22
 
148
- def close_pool(self) -> None:
149
- return
150
23
 
151
- def provide_pool(self, *args: Any, **kwargs: Any) -> None:
152
- """This database backend has not implemented the pooling configurations."""
153
- return
24
+ __all__ = ("SQLSpec",)
154
25
 
155
-
156
- class NoPoolAsyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
157
- """Base class for an async database configurations that do not implement a pool."""
158
-
159
- __is_async__ = True
160
- __supports_connection_pooling__ = False
161
- pool_instance: None = None
162
-
163
- async def create_pool(self) -> None:
164
- """This database backend has not implemented the pooling configurations."""
165
- return
166
-
167
- async def close_pool(self) -> None:
168
- return
169
-
170
- def provide_pool(self, *args: Any, **kwargs: Any) -> None:
171
- """This database backend has not implemented the pooling configurations."""
172
- return
173
-
174
-
175
- @dataclass
176
- class GenericPoolConfig:
177
- """Generic Database Pool Configuration."""
178
-
179
-
180
- @dataclass
181
- class SyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
182
- """Generic Sync Database Configuration."""
183
-
184
- __is_async__ = False
185
- __supports_connection_pooling__ = True
186
-
187
-
188
- @dataclass
189
- class AsyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
190
- """Generic Async Database Configuration."""
191
-
192
- __is_async__ = True
193
- __supports_connection_pooling__ = True
26
+ logger = get_logger()
194
27
 
195
28
 
196
29
  class SQLSpec:
@@ -200,34 +33,64 @@ class SQLSpec:
200
33
 
201
34
  def __init__(self) -> None:
202
35
  self._configs: dict[Any, DatabaseConfigProtocol[Any, Any, Any]] = {}
203
- # Register the cleanup handler to run at program exit
204
36
  atexit.register(self._cleanup_pools)
205
37
 
38
+ @staticmethod
39
+ def _get_config_name(obj: Any) -> str:
40
+ """Get display name for configuration object."""
41
+ # Try to get __name__ attribute if it exists, otherwise use str()
42
+ return getattr(obj, "__name__", str(obj))
43
+
206
44
  def _cleanup_pools(self) -> None:
207
- """Clean up all open database pools at program exit."""
208
- for config in self._configs.values():
209
- if config.support_connection_pooling and config.pool_instance is not None:
210
- with contextlib.suppress(Exception):
211
- ensure_async_(config.close_pool)()
45
+ """Clean up all registered connection pools."""
46
+ cleaned_count = 0
47
+
48
+ for config_type, config in self._configs.items():
49
+ if config.supports_connection_pooling:
50
+ try:
51
+ if config.is_async:
52
+ close_pool_awaitable = config.close_pool()
53
+ if close_pool_awaitable is not None:
54
+ try:
55
+ loop = asyncio.get_running_loop()
56
+ if loop.is_running():
57
+ _task = asyncio.ensure_future(close_pool_awaitable, loop=loop) # noqa: RUF006
58
+
59
+ else:
60
+ asyncio.run(cast("Coroutine[Any, Any, None]", close_pool_awaitable))
61
+ except RuntimeError: # No running event loop
62
+ asyncio.run(cast("Coroutine[Any, Any, None]", close_pool_awaitable))
63
+ else:
64
+ config.close_pool()
65
+ cleaned_count += 1
66
+ except Exception as e:
67
+ logger.warning("Failed to clean up pool for config %s: %s", config_type.__name__, e)
68
+
69
+ self._configs.clear()
70
+ logger.info("Pool cleanup completed. Cleaned %d pools.", cleaned_count)
212
71
 
213
72
  @overload
214
- def add_config(self, config: "SyncConfigT") -> "type[SyncConfigT]": ...
73
+ def add_config(self, config: "SyncConfigT") -> "type[SyncConfigT]": # pyright: ignore[reportInvalidTypeVarUse]
74
+ ...
215
75
 
216
76
  @overload
217
- def add_config(self, config: "AsyncConfigT") -> "type[AsyncConfigT]": ...
77
+ def add_config(self, config: "AsyncConfigT") -> "type[AsyncConfigT]": # pyright: ignore[reportInvalidTypeVarUse]
78
+ ...
218
79
 
219
- def add_config(
220
- self,
221
- config: "Union[SyncConfigT, AsyncConfigT]",
222
- ) -> "Union[Annotated[type[SyncConfigT], int], Annotated[type[AsyncConfigT], int]]": # pyright: ignore[reportInvalidTypeVarUse]
223
- """Add a new configuration to the manager.
80
+ def add_config(self, config: "Union[SyncConfigT, AsyncConfigT]") -> "type[Union[SyncConfigT, AsyncConfigT]]": # pyright: ignore[reportInvalidTypeVarUse]
81
+ """Add a configuration instance to the registry.
82
+
83
+ Args:
84
+ config: The configuration instance to add.
224
85
 
225
86
  Returns:
226
- A unique type key that can be used to retrieve the configuration later.
87
+ The type of the added configuration, annotated with its ID for potential use in type systems.
227
88
  """
228
- key = Annotated[type(config), id(config)] # type: ignore[valid-type]
229
- self._configs[key] = config
230
- return key # type: ignore[return-value] # pyright: ignore[reportReturnType]
89
+ config_type = type(config)
90
+ if config_type in self._configs:
91
+ logger.warning("Configuration for %s already exists. Overwriting.", config_type.__name__)
92
+ self._configs[config_type] = config
93
+ return config_type
231
94
 
232
95
  @overload
233
96
  def get_config(self, name: "type[SyncConfigT]") -> "SyncConfigT": ...
@@ -236,21 +99,26 @@ class SQLSpec:
236
99
  def get_config(self, name: "type[AsyncConfigT]") -> "AsyncConfigT": ...
237
100
 
238
101
  def get_config(
239
- self,
240
- name: "Union[type[DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]], Any]",
102
+ self, name: "Union[type[DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]], Any]"
241
103
  ) -> "DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]":
242
- """Retrieve a configuration by its type.
104
+ """Retrieve a configuration instance by its type or a key.
105
+
106
+ Args:
107
+ name: The type of the configuration or a key associated with it.
243
108
 
244
109
  Returns:
245
- DatabaseConfigProtocol: The configuration instance for the given type.
110
+ The configuration instance.
246
111
 
247
112
  Raises:
248
- KeyError: If no configuration is found for the given type.
113
+ KeyError: If the configuration is not found.
249
114
  """
250
115
  config = self._configs.get(name)
251
116
  if not config:
117
+ logger.error("No configuration found for %s", name)
252
118
  msg = f"No configuration found for {name}"
253
119
  raise KeyError(msg)
120
+
121
+ logger.debug("Retrieved configuration: %s", self._get_config_name(name))
254
122
  return config
255
123
 
256
124
  @overload
@@ -258,7 +126,9 @@ class SQLSpec:
258
126
  self,
259
127
  name: Union[
260
128
  "type[NoPoolSyncConfig[ConnectionT, DriverT]]",
261
- "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]", # pyright: ignore[reportInvalidTypeVarUse]
129
+ "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
130
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
131
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
262
132
  ],
263
133
  ) -> "ConnectionT": ...
264
134
 
@@ -267,7 +137,9 @@ class SQLSpec:
267
137
  self,
268
138
  name: Union[
269
139
  "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
270
- "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]", # pyright: ignore[reportInvalidTypeVarUse]
140
+ "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
141
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
142
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
271
143
  ],
272
144
  ) -> "Awaitable[ConnectionT]": ...
273
145
 
@@ -278,17 +150,28 @@ class SQLSpec:
278
150
  "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
279
151
  "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
280
152
  "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
153
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
154
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
155
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
156
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
281
157
  ],
282
158
  ) -> "Union[ConnectionT, Awaitable[ConnectionT]]":
283
- """Create and return a new database connection from the specified configuration.
159
+ """Get a database connection for the specified configuration.
284
160
 
285
161
  Args:
286
- name: The configuration type to use for creating the connection.
162
+ name: The configuration name or instance.
287
163
 
288
164
  Returns:
289
- Either a connection instance or an awaitable that resolves to a connection instance.
165
+ A database connection or an awaitable yielding a connection.
290
166
  """
291
- config = self.get_config(name)
167
+ if isinstance(name, (NoPoolSyncConfig, NoPoolAsyncConfig, SyncDatabaseConfig, AsyncDatabaseConfig)):
168
+ config = name
169
+ config_name = config.__class__.__name__
170
+ else:
171
+ config = self.get_config(name)
172
+ config_name = self._get_config_name(name)
173
+
174
+ logger.debug("Getting connection for config: %s", config_name, extra={"config_type": config_name})
292
175
  return config.create_connection()
293
176
 
294
177
  @overload
@@ -297,6 +180,8 @@ class SQLSpec:
297
180
  name: Union[
298
181
  "type[NoPoolSyncConfig[ConnectionT, DriverT]]",
299
182
  "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
183
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
184
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
300
185
  ],
301
186
  ) -> "DriverT": ...
302
187
 
@@ -306,6 +191,8 @@ class SQLSpec:
306
191
  name: Union[
307
192
  "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
308
193
  "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
194
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
195
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
309
196
  ],
310
197
  ) -> "Awaitable[DriverT]": ...
311
198
 
@@ -316,25 +203,45 @@ class SQLSpec:
316
203
  "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
317
204
  "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
318
205
  "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
206
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
207
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
208
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
209
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
319
210
  ],
320
211
  ) -> "Union[DriverT, Awaitable[DriverT]]":
321
- """Create and return a new database session from the specified configuration.
212
+ """Get a database session (driver adapter) for the specified configuration.
322
213
 
323
214
  Args:
324
- name: The configuration type to use for creating the session.
215
+ name: The configuration name or instance.
325
216
 
326
217
  Returns:
327
- Either a driver instance or an awaitable that resolves to a driver instance.
218
+ A driver adapter instance or an awaitable yielding one.
328
219
  """
329
- config = self.get_config(name)
330
- connection = self.get_connection(name)
331
- if isinstance(connection, Awaitable):
220
+ if isinstance(name, (NoPoolSyncConfig, NoPoolAsyncConfig, SyncDatabaseConfig, AsyncDatabaseConfig)):
221
+ config = name
222
+ config_name = config.__class__.__name__
223
+ else:
224
+ config = self.get_config(name)
225
+ config_name = self._get_config_name(name)
226
+
227
+ logger.debug("Getting session for config: %s", config_name, extra={"config_type": config_name})
228
+
229
+ connection_obj = self.get_connection(name)
230
+
231
+ if isinstance(connection_obj, Awaitable):
232
+
233
+ async def _create_driver_async() -> "DriverT":
234
+ resolved_connection = await connection_obj # pyright: ignore
235
+ return cast( # pyright: ignore
236
+ "DriverT",
237
+ config.driver_type(connection=resolved_connection, default_row_type=config.default_row_type),
238
+ )
332
239
 
333
- async def _create_session() -> DriverT:
334
- return cast("DriverT", config.driver_type(await connection)) # pyright: ignore
240
+ return _create_driver_async()
335
241
 
336
- return _create_session()
337
- return cast("DriverT", config.driver_type(connection)) # pyright: ignore
242
+ return cast( # pyright: ignore
243
+ "DriverT", config.driver_type(connection=connection_obj, default_row_type=config.default_row_type)
244
+ )
338
245
 
339
246
  @overload
340
247
  def provide_connection(
@@ -342,6 +249,8 @@ class SQLSpec:
342
249
  name: Union[
343
250
  "type[NoPoolSyncConfig[ConnectionT, DriverT]]",
344
251
  "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
252
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
253
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
345
254
  ],
346
255
  *args: Any,
347
256
  **kwargs: Any,
@@ -353,6 +262,8 @@ class SQLSpec:
353
262
  name: Union[
354
263
  "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
355
264
  "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
265
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
266
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
356
267
  ],
357
268
  *args: Any,
358
269
  **kwargs: Any,
@@ -365,6 +276,10 @@ class SQLSpec:
365
276
  "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
366
277
  "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
367
278
  "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
279
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
280
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
281
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
282
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
368
283
  ],
369
284
  *args: Any,
370
285
  **kwargs: Any,
@@ -372,14 +287,22 @@ class SQLSpec:
372
287
  """Create and provide a database connection from the specified configuration.
373
288
 
374
289
  Args:
375
- name: The configuration type to use for creating the connection.
376
- *args: Positional arguments to pass to the configuration's provide_connection method.
377
- **kwargs: Keyword arguments to pass to the configuration's provide_connection method.
290
+ name: The configuration name or instance.
291
+ *args: Positional arguments to pass to the config's provide_connection.
292
+ **kwargs: Keyword arguments to pass to the config's provide_connection.
293
+
378
294
 
379
295
  Returns:
380
- Either a synchronous or asynchronous context manager that provides a database connection.
296
+ A sync or async context manager yielding a connection.
381
297
  """
382
- config = self.get_config(name)
298
+ if isinstance(name, (NoPoolSyncConfig, NoPoolAsyncConfig, SyncDatabaseConfig, AsyncDatabaseConfig)):
299
+ config = name
300
+ config_name = config.__class__.__name__
301
+ else:
302
+ config = self.get_config(name)
303
+ config_name = self._get_config_name(name)
304
+
305
+ logger.debug("Providing connection context for config: %s", config_name, extra={"config_type": config_name})
383
306
  return config.provide_connection(*args, **kwargs)
384
307
 
385
308
  @overload
@@ -388,6 +311,8 @@ class SQLSpec:
388
311
  name: Union[
389
312
  "type[NoPoolSyncConfig[ConnectionT, DriverT]]",
390
313
  "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
314
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
315
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
391
316
  ],
392
317
  *args: Any,
393
318
  **kwargs: Any,
@@ -399,6 +324,8 @@ class SQLSpec:
399
324
  name: Union[
400
325
  "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
401
326
  "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
327
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
328
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
402
329
  ],
403
330
  *args: Any,
404
331
  **kwargs: Any,
@@ -411,6 +338,10 @@ class SQLSpec:
411
338
  "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
412
339
  "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
413
340
  "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
341
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
342
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
343
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
344
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
414
345
  ],
415
346
  *args: Any,
416
347
  **kwargs: Any,
@@ -418,26 +349,38 @@ class SQLSpec:
418
349
  """Create and provide a database session from the specified configuration.
419
350
 
420
351
  Args:
421
- name: The configuration type to use for creating the session.
422
- *args: Positional arguments to pass to the configuration's provide_session method.
423
- **kwargs: Keyword arguments to pass to the configuration's provide_session method.
352
+ name: The configuration name or instance.
353
+ *args: Positional arguments to pass to the config's provide_session.
354
+ **kwargs: Keyword arguments to pass to the config's provide_session.
424
355
 
425
356
  Returns:
426
- Either a synchronous or asynchronous context manager that provides a database session.
357
+ A sync or async context manager yielding a driver adapter instance.
427
358
  """
428
- config = self.get_config(name)
359
+ if isinstance(name, (NoPoolSyncConfig, NoPoolAsyncConfig, SyncDatabaseConfig, AsyncDatabaseConfig)):
360
+ config = name
361
+ config_name = config.__class__.__name__
362
+ else:
363
+ config = self.get_config(name)
364
+ config_name = self._get_config_name(name)
365
+
366
+ logger.debug("Providing session context for config: %s", config_name, extra={"config_type": config_name})
429
367
  return config.provide_session(*args, **kwargs)
430
368
 
431
369
  @overload
432
370
  def get_pool(
433
- self, name: "type[Union[NoPoolSyncConfig[ConnectionT, DriverT], NoPoolAsyncConfig[ConnectionT, DriverT]]]"
434
- ) -> "None": ... # pyright: ignore[reportInvalidTypeVarUse]
435
-
371
+ self,
372
+ name: "Union[type[Union[NoPoolSyncConfig[ConnectionT, DriverT], NoPoolAsyncConfig[ConnectionT, DriverT]]], NoPoolSyncConfig[ConnectionT, DriverT], NoPoolAsyncConfig[ConnectionT, DriverT]]",
373
+ ) -> "None": ...
436
374
  @overload
437
- def get_pool(self, name: "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]") -> "type[PoolT]": ... # pyright: ignore[reportInvalidTypeVarUse]
438
-
375
+ def get_pool(
376
+ self,
377
+ name: "Union[type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]], SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
378
+ ) -> "type[PoolT]": ...
439
379
  @overload
440
- def get_pool(self, name: "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]") -> "Awaitable[type[PoolT]]": ... # pyright: ignore[reportInvalidTypeVarUse]
380
+ def get_pool(
381
+ self,
382
+ name: "Union[type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]],AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
383
+ ) -> "Awaitable[type[PoolT]]": ...
441
384
 
442
385
  def get_pool(
443
386
  self,
@@ -446,20 +389,32 @@ class SQLSpec:
446
389
  "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
447
390
  "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
448
391
  "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
392
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
393
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
394
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
395
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
449
396
  ],
450
397
  ) -> "Union[type[PoolT], Awaitable[type[PoolT]], None]":
451
- """Create and return a connection pool from the specified configuration.
398
+ """Get the connection pool for the specified configuration.
452
399
 
453
400
  Args:
454
- name: The configuration type to use for creating the pool.
401
+ name: The configuration name or instance.
455
402
 
456
403
  Returns:
457
- Either a pool instance, an awaitable that resolves to a pool instance, or None
458
- if the configuration does not support connection pooling.
404
+ The connection pool, an awaitable yielding the pool, or None if not supported.
459
405
  """
460
- config = self.get_config(name)
461
- if config.support_connection_pooling:
406
+ config = (
407
+ name
408
+ if isinstance(name, (NoPoolSyncConfig, NoPoolAsyncConfig, SyncDatabaseConfig, AsyncDatabaseConfig))
409
+ else self.get_config(name)
410
+ )
411
+ config_name = config.__class__.__name__
412
+
413
+ if config.supports_connection_pooling:
414
+ logger.debug("Getting pool for config: %s", config_name, extra={"config_type": config_name})
462
415
  return cast("Union[type[PoolT], Awaitable[type[PoolT]]]", config.create_pool())
416
+
417
+ logger.debug("Config %s does not support connection pooling", config_name)
463
418
  return None
464
419
 
465
420
  @overload
@@ -468,6 +423,8 @@ class SQLSpec:
468
423
  name: Union[
469
424
  "type[NoPoolSyncConfig[ConnectionT, DriverT]]",
470
425
  "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
426
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
427
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
471
428
  ],
472
429
  ) -> "None": ...
473
430
 
@@ -477,6 +434,8 @@ class SQLSpec:
477
434
  name: Union[
478
435
  "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
479
436
  "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
437
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
438
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
480
439
  ],
481
440
  ) -> "Awaitable[None]": ...
482
441
 
@@ -487,553 +446,30 @@ class SQLSpec:
487
446
  "type[NoPoolAsyncConfig[ConnectionT, DriverT]]",
488
447
  "type[SyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
489
448
  "type[AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]]",
449
+ "NoPoolSyncConfig[ConnectionT, DriverT]",
450
+ "SyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
451
+ "NoPoolAsyncConfig[ConnectionT, DriverT]",
452
+ "AsyncDatabaseConfig[ConnectionT, PoolT, DriverT]",
490
453
  ],
491
454
  ) -> "Optional[Awaitable[None]]":
492
455
  """Close the connection pool for the specified configuration.
493
456
 
494
457
  Args:
495
- name: The configuration type whose pool to close.
458
+ name: The configuration name or instance.
496
459
 
497
460
  Returns:
498
- An awaitable if the configuration is async, otherwise None.
461
+ None, or an awaitable if closing an async pool.
499
462
  """
500
- config = self.get_config(name)
501
- if config.support_connection_pooling:
463
+ if isinstance(name, (NoPoolSyncConfig, NoPoolAsyncConfig, SyncDatabaseConfig, AsyncDatabaseConfig)):
464
+ config = name
465
+ config_name = config.__class__.__name__
466
+ else:
467
+ config = self.get_config(name)
468
+ config_name = self._get_config_name(name)
469
+
470
+ if config.supports_connection_pooling:
471
+ logger.debug("Closing pool for config: %s", config_name, extra={"config_type": config_name})
502
472
  return config.close_pool()
503
- return None
504
-
505
-
506
- class CommonDriverAttributes(Generic[ConnectionT]):
507
- """Common attributes and methods for driver adapters."""
508
-
509
- dialect: str
510
- """The SQL dialect supported by the underlying database driver (e.g., 'postgres', 'mysql')."""
511
- connection: ConnectionT
512
- """The connection to the underlying database."""
513
- __supports_arrow__: ClassVar[bool] = False
514
- """Indicates if the driver supports Apache Arrow operations."""
515
-
516
- def _connection(self, connection: "Optional[ConnectionT]" = None) -> "ConnectionT":
517
- return connection if connection is not None else self.connection
518
-
519
- @staticmethod
520
- def check_not_found(item_or_none: Optional[T] = None) -> T:
521
- """Raise :exc:`sqlspec.exceptions.NotFoundError` if ``item_or_none`` is ``None``.
522
-
523
- Args:
524
- item_or_none: Item to be tested for existence.
525
-
526
- Raises:
527
- NotFoundError: If ``item_or_none`` is ``None``
528
-
529
- Returns:
530
- The item, if it exists.
531
- """
532
- if item_or_none is None:
533
- msg = "No result found when one was expected"
534
- raise NotFoundError(msg)
535
- return item_or_none
536
-
537
- def _process_sql_params(
538
- self,
539
- sql: str,
540
- parameters: "Optional[StatementParameterType]" = None,
541
- *filters: "StatementFilter",
542
- **kwargs: Any,
543
- ) -> "tuple[str, Optional[Union[tuple[Any, ...], list[Any], dict[str, Any]]]]":
544
- """Process SQL query and parameters using SQLStatement for validation and formatting.
545
-
546
- Args:
547
- sql: The SQL query string.
548
- parameters: Parameters for the query.
549
- *filters: Statement filters to apply.
550
- **kwargs: Additional keyword arguments to merge with parameters if parameters is a dict.
551
-
552
- Returns:
553
- A tuple containing the processed SQL query and parameters.
554
- """
555
- # Instantiate SQLStatement with parameters and kwargs for internal merging
556
- stmt = SQLStatement(sql=sql, parameters=parameters, kwargs=kwargs or None)
557
-
558
- # Apply all statement filters
559
- for filter_obj in filters:
560
- stmt = stmt.apply_filter(filter_obj)
561
-
562
- # Process uses the merged parameters internally
563
- processed = stmt.process()
564
- return processed[0], processed[1] # Return only the SQL and parameters, discard the third element
565
-
566
-
567
- class SyncDriverAdapterProtocol(CommonDriverAttributes[ConnectionT], ABC, Generic[ConnectionT]):
568
- connection: "ConnectionT"
569
-
570
- def __init__(self, connection: "ConnectionT", **kwargs: Any) -> None:
571
- self.connection = connection
572
-
573
- @overload
574
- @abstractmethod
575
- def select(
576
- self,
577
- sql: str,
578
- parameters: "Optional[StatementParameterType]" = None,
579
- *filters: "StatementFilter",
580
- connection: "Optional[ConnectionT]" = None,
581
- schema_type: None = None,
582
- **kwargs: Any,
583
- ) -> "Sequence[dict[str, Any]]": ...
584
-
585
- @overload
586
- @abstractmethod
587
- def select(
588
- self,
589
- sql: str,
590
- parameters: "Optional[StatementParameterType]" = None,
591
- *filters: "StatementFilter",
592
- connection: "Optional[ConnectionT]" = None,
593
- schema_type: "type[ModelDTOT]",
594
- **kwargs: Any,
595
- ) -> "Sequence[ModelDTOT]": ...
596
-
597
- @abstractmethod
598
- def select(
599
- self,
600
- sql: str,
601
- parameters: "Optional[StatementParameterType]" = None,
602
- *filters: "StatementFilter",
603
- connection: "Optional[ConnectionT]" = None,
604
- schema_type: Optional[type[ModelDTOT]] = None,
605
- **kwargs: Any,
606
- ) -> "Sequence[Union[ModelDTOT, dict[str, Any]]]": ...
607
-
608
- @overload
609
- @abstractmethod
610
- def select_one(
611
- self,
612
- sql: str,
613
- parameters: "Optional[StatementParameterType]" = None,
614
- *filters: "StatementFilter",
615
- connection: "Optional[ConnectionT]" = None,
616
- schema_type: None = None,
617
- **kwargs: Any,
618
- ) -> "dict[str, Any]": ...
619
-
620
- @overload
621
- @abstractmethod
622
- def select_one(
623
- self,
624
- sql: str,
625
- parameters: "Optional[StatementParameterType]" = None,
626
- *filters: "StatementFilter",
627
- connection: "Optional[ConnectionT]" = None,
628
- schema_type: "type[ModelDTOT]",
629
- **kwargs: Any,
630
- ) -> "ModelDTOT": ...
631
-
632
- @abstractmethod
633
- def select_one(
634
- self,
635
- sql: str,
636
- parameters: Optional[StatementParameterType] = None,
637
- *filters: "StatementFilter",
638
- connection: Optional[ConnectionT] = None,
639
- schema_type: Optional[type[ModelDTOT]] = None,
640
- **kwargs: Any,
641
- ) -> "Union[ModelDTOT, dict[str, Any]]": ...
642
-
643
- @overload
644
- @abstractmethod
645
- def select_one_or_none(
646
- self,
647
- sql: str,
648
- parameters: "Optional[StatementParameterType]" = None,
649
- *filters: "StatementFilter",
650
- connection: "Optional[ConnectionT]" = None,
651
- schema_type: None = None,
652
- **kwargs: Any,
653
- ) -> "Optional[dict[str, Any]]": ...
654
-
655
- @overload
656
- @abstractmethod
657
- def select_one_or_none(
658
- self,
659
- sql: str,
660
- parameters: "Optional[StatementParameterType]" = None,
661
- *filters: "StatementFilter",
662
- connection: "Optional[ConnectionT]" = None,
663
- schema_type: "type[ModelDTOT]",
664
- **kwargs: Any,
665
- ) -> "Optional[ModelDTOT]": ...
666
-
667
- @abstractmethod
668
- def select_one_or_none(
669
- self,
670
- sql: str,
671
- parameters: Optional[StatementParameterType] = None,
672
- *filters: "StatementFilter",
673
- connection: Optional[ConnectionT] = None,
674
- schema_type: Optional[type[ModelDTOT]] = None,
675
- **kwargs: Any,
676
- ) -> "Optional[Union[ModelDTOT, dict[str, Any]]]": ...
677
-
678
- @overload
679
- @abstractmethod
680
- def select_value(
681
- self,
682
- sql: str,
683
- parameters: "Optional[StatementParameterType]" = None,
684
- *filters: "StatementFilter",
685
- connection: "Optional[ConnectionT]" = None,
686
- schema_type: None = None,
687
- **kwargs: Any,
688
- ) -> "Any": ...
689
-
690
- @overload
691
- @abstractmethod
692
- def select_value(
693
- self,
694
- sql: str,
695
- parameters: "Optional[StatementParameterType]" = None,
696
- *filters: "StatementFilter",
697
- connection: "Optional[ConnectionT]" = None,
698
- schema_type: "type[T]",
699
- **kwargs: Any,
700
- ) -> "T": ...
701
-
702
- @abstractmethod
703
- def select_value(
704
- self,
705
- sql: str,
706
- parameters: Optional[StatementParameterType] = None,
707
- *filters: "StatementFilter",
708
- connection: Optional[ConnectionT] = None,
709
- schema_type: Optional[type[T]] = None,
710
- **kwargs: Any,
711
- ) -> "Union[T, Any]": ...
712
-
713
- @overload
714
- @abstractmethod
715
- def select_value_or_none(
716
- self,
717
- sql: str,
718
- parameters: "Optional[StatementParameterType]" = None,
719
- *filters: "StatementFilter",
720
- connection: "Optional[ConnectionT]" = None,
721
- schema_type: None = None,
722
- **kwargs: Any,
723
- ) -> "Optional[Any]": ...
724
-
725
- @overload
726
- @abstractmethod
727
- def select_value_or_none(
728
- self,
729
- sql: str,
730
- parameters: "Optional[StatementParameterType]" = None,
731
- *filters: "StatementFilter",
732
- connection: "Optional[ConnectionT]" = None,
733
- schema_type: "type[T]",
734
- **kwargs: Any,
735
- ) -> "Optional[T]": ...
736
-
737
- @abstractmethod
738
- def select_value_or_none(
739
- self,
740
- sql: str,
741
- parameters: Optional[StatementParameterType] = None,
742
- *filters: "StatementFilter",
743
- connection: Optional[ConnectionT] = None,
744
- schema_type: Optional[type[T]] = None,
745
- **kwargs: Any,
746
- ) -> "Optional[Union[T, Any]]": ...
747
-
748
- @abstractmethod
749
- def insert_update_delete(
750
- self,
751
- sql: str,
752
- parameters: Optional[StatementParameterType] = None,
753
- *filters: "StatementFilter",
754
- connection: Optional[ConnectionT] = None,
755
- **kwargs: Any,
756
- ) -> int: ...
757
-
758
- @overload
759
- @abstractmethod
760
- def insert_update_delete_returning(
761
- self,
762
- sql: str,
763
- parameters: "Optional[StatementParameterType]" = None,
764
- *filters: "StatementFilter",
765
- connection: "Optional[ConnectionT]" = None,
766
- schema_type: None = None,
767
- **kwargs: Any,
768
- ) -> "dict[str, Any]": ...
769
-
770
- @overload
771
- @abstractmethod
772
- def insert_update_delete_returning(
773
- self,
774
- sql: str,
775
- parameters: "Optional[StatementParameterType]" = None,
776
- *filters: "StatementFilter",
777
- connection: "Optional[ConnectionT]" = None,
778
- schema_type: "type[ModelDTOT]",
779
- **kwargs: Any,
780
- ) -> "ModelDTOT": ...
781
-
782
- @abstractmethod
783
- def insert_update_delete_returning(
784
- self,
785
- sql: str,
786
- parameters: Optional[StatementParameterType] = None,
787
- *filters: "StatementFilter",
788
- connection: Optional[ConnectionT] = None,
789
- schema_type: Optional[type[ModelDTOT]] = None,
790
- **kwargs: Any,
791
- ) -> "Union[ModelDTOT, dict[str, Any]]": ...
792
-
793
- @abstractmethod
794
- def execute_script(
795
- self,
796
- sql: str,
797
- parameters: Optional[StatementParameterType] = None,
798
- connection: Optional[ConnectionT] = None,
799
- **kwargs: Any,
800
- ) -> str: ...
801
-
802
-
803
- class AsyncDriverAdapterProtocol(CommonDriverAttributes[ConnectionT], ABC, Generic[ConnectionT]):
804
- connection: "ConnectionT"
805
-
806
- def __init__(self, connection: "ConnectionT") -> None:
807
- self.connection = connection
808
-
809
- @overload
810
- @abstractmethod
811
- async def select(
812
- self,
813
- sql: str,
814
- parameters: "Optional[StatementParameterType]" = None,
815
- *filters: "StatementFilter",
816
- connection: "Optional[ConnectionT]" = None,
817
- schema_type: None = None,
818
- **kwargs: Any,
819
- ) -> "Sequence[dict[str, Any]]": ...
820
-
821
- @overload
822
- @abstractmethod
823
- async def select(
824
- self,
825
- sql: str,
826
- parameters: "Optional[StatementParameterType]" = None,
827
- *filters: "StatementFilter",
828
- connection: "Optional[ConnectionT]" = None,
829
- schema_type: "type[ModelDTOT]",
830
- **kwargs: Any,
831
- ) -> "Sequence[ModelDTOT]": ...
832
-
833
- @abstractmethod
834
- async def select(
835
- self,
836
- sql: str,
837
- parameters: "Optional[StatementParameterType]" = None,
838
- *filters: "StatementFilter",
839
- connection: "Optional[ConnectionT]" = None,
840
- schema_type: "Optional[type[ModelDTOT]]" = None,
841
- **kwargs: Any,
842
- ) -> "Sequence[Union[ModelDTOT, dict[str, Any]]]": ...
843
-
844
- @overload
845
- @abstractmethod
846
- async def select_one(
847
- self,
848
- sql: str,
849
- parameters: "Optional[StatementParameterType]" = None,
850
- *filters: "StatementFilter",
851
- connection: "Optional[ConnectionT]" = None,
852
- schema_type: None = None,
853
- **kwargs: Any,
854
- ) -> "dict[str, Any]": ...
855
-
856
- @overload
857
- @abstractmethod
858
- async def select_one(
859
- self,
860
- sql: str,
861
- parameters: "Optional[StatementParameterType]" = None,
862
- *filters: "StatementFilter",
863
- connection: "Optional[ConnectionT]" = None,
864
- schema_type: "type[ModelDTOT]",
865
- **kwargs: Any,
866
- ) -> "ModelDTOT": ...
867
-
868
- @abstractmethod
869
- async def select_one(
870
- self,
871
- sql: str,
872
- parameters: "Optional[StatementParameterType]" = None,
873
- *filters: "StatementFilter",
874
- connection: "Optional[ConnectionT]" = None,
875
- schema_type: "Optional[type[ModelDTOT]]" = None,
876
- **kwargs: Any,
877
- ) -> "Union[ModelDTOT, dict[str, Any]]": ...
878
-
879
- @overload
880
- @abstractmethod
881
- async def select_one_or_none(
882
- self,
883
- sql: str,
884
- parameters: "Optional[StatementParameterType]" = None,
885
- *filters: "StatementFilter",
886
- connection: "Optional[ConnectionT]" = None,
887
- schema_type: None = None,
888
- **kwargs: Any,
889
- ) -> "Optional[dict[str, Any]]": ...
890
-
891
- @overload
892
- @abstractmethod
893
- async def select_one_or_none(
894
- self,
895
- sql: str,
896
- parameters: "Optional[StatementParameterType]" = None,
897
- *filters: "StatementFilter",
898
- connection: "Optional[ConnectionT]" = None,
899
- schema_type: "type[ModelDTOT]",
900
- **kwargs: Any,
901
- ) -> "Optional[ModelDTOT]": ...
902
-
903
- @abstractmethod
904
- async def select_one_or_none(
905
- self,
906
- sql: str,
907
- parameters: "Optional[StatementParameterType]" = None,
908
- *filters: "StatementFilter",
909
- connection: "Optional[ConnectionT]" = None,
910
- schema_type: "Optional[type[ModelDTOT]]" = None,
911
- **kwargs: Any,
912
- ) -> "Optional[Union[ModelDTOT, dict[str, Any]]]": ...
913
-
914
- @overload
915
- @abstractmethod
916
- async def select_value(
917
- self,
918
- sql: str,
919
- parameters: "Optional[StatementParameterType]" = None,
920
- *filters: "StatementFilter",
921
- connection: "Optional[ConnectionT]" = None,
922
- schema_type: None = None,
923
- **kwargs: Any,
924
- ) -> "Any": ...
925
-
926
- @overload
927
- @abstractmethod
928
- async def select_value(
929
- self,
930
- sql: str,
931
- parameters: "Optional[StatementParameterType]" = None,
932
- *filters: "StatementFilter",
933
- connection: "Optional[ConnectionT]" = None,
934
- schema_type: "type[T]",
935
- **kwargs: Any,
936
- ) -> "T": ...
937
-
938
- @abstractmethod
939
- async def select_value(
940
- self,
941
- sql: str,
942
- parameters: "Optional[StatementParameterType]" = None,
943
- *filters: "StatementFilter",
944
- connection: "Optional[ConnectionT]" = None,
945
- schema_type: "Optional[type[T]]" = None,
946
- **kwargs: Any,
947
- ) -> "Union[T, Any]": ...
948
-
949
- @overload
950
- @abstractmethod
951
- async def select_value_or_none(
952
- self,
953
- sql: str,
954
- parameters: "Optional[StatementParameterType]" = None,
955
- *filters: "StatementFilter",
956
- connection: "Optional[ConnectionT]" = None,
957
- schema_type: None = None,
958
- **kwargs: Any,
959
- ) -> "Optional[Any]": ...
960
-
961
- @overload
962
- @abstractmethod
963
- async def select_value_or_none(
964
- self,
965
- sql: str,
966
- parameters: "Optional[StatementParameterType]" = None,
967
- *filters: "StatementFilter",
968
- connection: "Optional[ConnectionT]" = None,
969
- schema_type: "type[T]",
970
- **kwargs: Any,
971
- ) -> "Optional[T]": ...
972
-
973
- @abstractmethod
974
- async def select_value_or_none(
975
- self,
976
- sql: str,
977
- parameters: "Optional[StatementParameterType]" = None,
978
- *filters: "StatementFilter",
979
- connection: "Optional[ConnectionT]" = None,
980
- schema_type: "Optional[type[T]]" = None,
981
- **kwargs: Any,
982
- ) -> "Optional[Union[T, Any]]": ...
983
473
 
984
- @abstractmethod
985
- async def insert_update_delete(
986
- self,
987
- sql: str,
988
- parameters: "Optional[StatementParameterType]" = None,
989
- *filters: "StatementFilter",
990
- connection: "Optional[ConnectionT]" = None,
991
- **kwargs: Any,
992
- ) -> int: ...
993
-
994
- @overload
995
- @abstractmethod
996
- async def insert_update_delete_returning(
997
- self,
998
- sql: str,
999
- parameters: "Optional[StatementParameterType]" = None,
1000
- *filters: "StatementFilter",
1001
- connection: "Optional[ConnectionT]" = None,
1002
- schema_type: None = None,
1003
- **kwargs: Any,
1004
- ) -> "dict[str, Any]": ...
1005
-
1006
- @overload
1007
- @abstractmethod
1008
- async def insert_update_delete_returning(
1009
- self,
1010
- sql: str,
1011
- parameters: "Optional[StatementParameterType]" = None,
1012
- *filters: "StatementFilter",
1013
- connection: "Optional[ConnectionT]" = None,
1014
- schema_type: "type[ModelDTOT]",
1015
- **kwargs: Any,
1016
- ) -> "ModelDTOT": ...
1017
-
1018
- @abstractmethod
1019
- async def insert_update_delete_returning(
1020
- self,
1021
- sql: str,
1022
- parameters: "Optional[StatementParameterType]" = None,
1023
- *filters: "StatementFilter",
1024
- connection: "Optional[ConnectionT]" = None,
1025
- schema_type: "Optional[type[ModelDTOT]]" = None,
1026
- **kwargs: Any,
1027
- ) -> "Union[ModelDTOT, dict[str, Any]]": ...
1028
-
1029
- @abstractmethod
1030
- async def execute_script(
1031
- self,
1032
- sql: str,
1033
- parameters: "Optional[StatementParameterType]" = None,
1034
- connection: "Optional[ConnectionT]" = None,
1035
- **kwargs: Any,
1036
- ) -> str: ...
1037
-
1038
-
1039
- DriverAdapterProtocol = Union[SyncDriverAdapterProtocol[ConnectionT], AsyncDriverAdapterProtocol[ConnectionT]]
474
+ logger.debug("Config %s does not support connection pooling - nothing to close", config_name)
475
+ return None