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.

Files changed (45) hide show
  1. sqlspec/_typing.py +39 -6
  2. sqlspec/adapters/adbc/__init__.py +2 -2
  3. sqlspec/adapters/adbc/config.py +34 -11
  4. sqlspec/adapters/adbc/driver.py +302 -111
  5. sqlspec/adapters/aiosqlite/__init__.py +2 -2
  6. sqlspec/adapters/aiosqlite/config.py +2 -2
  7. sqlspec/adapters/aiosqlite/driver.py +164 -42
  8. sqlspec/adapters/asyncmy/__init__.py +3 -3
  9. sqlspec/adapters/asyncmy/config.py +11 -12
  10. sqlspec/adapters/asyncmy/driver.py +161 -37
  11. sqlspec/adapters/asyncpg/__init__.py +5 -5
  12. sqlspec/adapters/asyncpg/config.py +17 -19
  13. sqlspec/adapters/asyncpg/driver.py +386 -96
  14. sqlspec/adapters/duckdb/__init__.py +2 -2
  15. sqlspec/adapters/duckdb/config.py +2 -2
  16. sqlspec/adapters/duckdb/driver.py +190 -60
  17. sqlspec/adapters/oracledb/__init__.py +8 -8
  18. sqlspec/adapters/oracledb/config/__init__.py +6 -6
  19. sqlspec/adapters/oracledb/config/_asyncio.py +9 -10
  20. sqlspec/adapters/oracledb/config/_sync.py +8 -9
  21. sqlspec/adapters/oracledb/driver.py +384 -45
  22. sqlspec/adapters/psqlpy/__init__.py +0 -0
  23. sqlspec/adapters/psqlpy/config.py +250 -0
  24. sqlspec/adapters/psqlpy/driver.py +481 -0
  25. sqlspec/adapters/psycopg/__init__.py +10 -5
  26. sqlspec/adapters/psycopg/config/__init__.py +6 -6
  27. sqlspec/adapters/psycopg/config/_async.py +12 -12
  28. sqlspec/adapters/psycopg/config/_sync.py +13 -13
  29. sqlspec/adapters/psycopg/driver.py +432 -222
  30. sqlspec/adapters/sqlite/__init__.py +2 -2
  31. sqlspec/adapters/sqlite/config.py +2 -2
  32. sqlspec/adapters/sqlite/driver.py +176 -72
  33. sqlspec/base.py +687 -161
  34. sqlspec/exceptions.py +30 -0
  35. sqlspec/extensions/litestar/config.py +6 -0
  36. sqlspec/extensions/litestar/handlers.py +25 -0
  37. sqlspec/extensions/litestar/plugin.py +8 -1
  38. sqlspec/statement.py +373 -0
  39. sqlspec/typing.py +10 -1
  40. {sqlspec-0.8.0.dist-info → sqlspec-0.9.1.dist-info}/METADATA +144 -2
  41. sqlspec-0.9.1.dist-info/RECORD +61 -0
  42. sqlspec-0.8.0.dist-info/RECORD +0 -57
  43. {sqlspec-0.8.0.dist-info → sqlspec-0.9.1.dist-info}/WHEEL +0 -0
  44. {sqlspec-0.8.0.dist-info → sqlspec-0.9.1.dist-info}/licenses/LICENSE +0 -0
  45. {sqlspec-0.8.0.dist-info → sqlspec-0.9.1.dist-info}/licenses/NOTICE +0 -0
@@ -14,7 +14,7 @@ if TYPE_CHECKING:
14
14
  from collections.abc import Generator, Sequence
15
15
 
16
16
 
17
- __all__ = ("DuckDB", "ExtensionConfig")
17
+ __all__ = ("DuckDBConfig", "ExtensionConfig")
18
18
 
19
19
 
20
20
  class ExtensionConfig(TypedDict):
@@ -69,7 +69,7 @@ class SecretConfig(TypedDict):
69
69
 
70
70
 
71
71
  @dataclass
72
- class DuckDB(NoPoolSyncConfig["DuckDBPyConnection", "DuckDBDriver"]):
72
+ class DuckDBConfig(NoPoolSyncConfig["DuckDBPyConnection", "DuckDBDriver"]):
73
73
  """Configuration for DuckDB database connections.
74
74
 
75
75
  This class provides configuration options for DuckDB database connections, wrapping all parameters
@@ -1,24 +1,24 @@
1
1
  from contextlib import contextmanager
2
- from typing import TYPE_CHECKING, Any, Optional, Union, cast
2
+ from typing import TYPE_CHECKING, Any, Optional, Union, cast, overload
3
3
 
4
- from sqlspec.base import SyncDriverAdapterProtocol, T
4
+ from sqlspec.base import SyncArrowBulkOperationsMixin, SyncDriverAdapterProtocol, T
5
5
 
6
6
  if TYPE_CHECKING:
7
- from collections.abc import Generator
7
+ from collections.abc import Generator, Sequence
8
8
 
9
9
  from duckdb import DuckDBPyConnection
10
10
 
11
- from sqlspec.typing import ModelDTOT, StatementParameterType
11
+ from sqlspec.typing import ArrowTable, ModelDTOT, StatementParameterType
12
12
 
13
13
  __all__ = ("DuckDBDriver",)
14
14
 
15
15
 
16
- class DuckDBDriver(SyncDriverAdapterProtocol["DuckDBPyConnection"]):
16
+ class DuckDBDriver(SyncArrowBulkOperationsMixin["DuckDBPyConnection"], SyncDriverAdapterProtocol["DuckDBPyConnection"]):
17
17
  """DuckDB Sync Driver Adapter."""
18
18
 
19
19
  connection: "DuckDBPyConnection"
20
20
  use_cursor: bool = True
21
- # param_style is inherited from CommonDriverAttributes
21
+ dialect: str = "duckdb"
22
22
 
23
23
  def __init__(self, connection: "DuckDBPyConnection", use_cursor: bool = True) -> None:
24
24
  self.connection = connection
@@ -27,7 +27,6 @@ class DuckDBDriver(SyncDriverAdapterProtocol["DuckDBPyConnection"]):
27
27
  # --- Helper Methods --- #
28
28
  def _cursor(self, connection: "DuckDBPyConnection") -> "DuckDBPyConnection":
29
29
  if self.use_cursor:
30
- # Ignore lack of type hint on cursor()
31
30
  return connection.cursor()
32
31
  return connection
33
32
 
@@ -40,20 +39,43 @@ class DuckDBDriver(SyncDriverAdapterProtocol["DuckDBPyConnection"]):
40
39
  finally:
41
40
  cursor.close()
42
41
  else:
43
- yield connection # Yield the connection directly
44
-
45
- # --- Public API Methods (Original Implementation + _process_sql_params) --- #
42
+ yield connection
46
43
 
44
+ # --- Public API Methods --- #
45
+ @overload
47
46
  def select(
48
47
  self,
49
48
  sql: str,
50
- parameters: Optional["StatementParameterType"] = None,
49
+ parameters: "Optional[StatementParameterType]" = None,
51
50
  /,
52
- connection: Optional["DuckDBPyConnection"] = None,
51
+ *,
52
+ connection: "Optional[DuckDBPyConnection]" = None,
53
+ schema_type: None = None,
54
+ **kwargs: Any,
55
+ ) -> "Sequence[dict[str, Any]]": ...
56
+ @overload
57
+ def select(
58
+ self,
59
+ sql: str,
60
+ parameters: "Optional[StatementParameterType]" = None,
61
+ /,
62
+ *,
63
+ connection: "Optional[DuckDBPyConnection]" = None,
64
+ schema_type: "type[ModelDTOT]",
65
+ **kwargs: Any,
66
+ ) -> "Sequence[ModelDTOT]": ...
67
+ def select(
68
+ self,
69
+ sql: str,
70
+ parameters: "Optional[StatementParameterType]" = None,
71
+ /,
72
+ *,
73
+ connection: "Optional[DuckDBPyConnection]" = None,
53
74
  schema_type: "Optional[type[ModelDTOT]]" = None,
54
- ) -> "list[Union[ModelDTOT, dict[str, Any]]]":
75
+ **kwargs: Any,
76
+ ) -> "Sequence[Union[ModelDTOT, dict[str, Any]]]":
55
77
  connection = self._connection(connection)
56
- sql, parameters = self._process_sql_params(sql, parameters)
78
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
57
79
  with self._with_cursor(connection) as cursor:
58
80
  cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
59
81
  results = cursor.fetchall() # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
@@ -66,21 +88,44 @@ class DuckDBDriver(SyncDriverAdapterProtocol["DuckDBPyConnection"]):
66
88
  return [cast("ModelDTOT", schema_type(**dict(zip(column_names, row)))) for row in results] # pyright: ignore[reportUnknownArgumentType]
67
89
  return [dict(zip(column_names, row)) for row in results] # pyright: ignore[reportUnknownArgumentType]
68
90
 
91
+ @overload
92
+ def select_one(
93
+ self,
94
+ sql: str,
95
+ parameters: "Optional[StatementParameterType]" = None,
96
+ /,
97
+ *,
98
+ connection: "Optional[DuckDBPyConnection]" = None,
99
+ schema_type: None = None,
100
+ **kwargs: Any,
101
+ ) -> "dict[str, Any]": ...
102
+ @overload
103
+ def select_one(
104
+ self,
105
+ sql: str,
106
+ parameters: "Optional[StatementParameterType]" = None,
107
+ /,
108
+ *,
109
+ connection: "Optional[DuckDBPyConnection]" = None,
110
+ schema_type: "type[ModelDTOT]",
111
+ **kwargs: Any,
112
+ ) -> "ModelDTOT": ...
69
113
  def select_one(
70
114
  self,
71
115
  sql: str,
72
116
  parameters: Optional["StatementParameterType"] = None,
73
117
  /,
118
+ *,
74
119
  connection: Optional["DuckDBPyConnection"] = None,
75
120
  schema_type: "Optional[type[ModelDTOT]]" = None,
121
+ **kwargs: Any,
76
122
  ) -> "Union[ModelDTOT, dict[str, Any]]":
77
123
  connection = self._connection(connection)
78
- sql, parameters = self._process_sql_params(sql, parameters)
79
-
124
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
80
125
  with self._with_cursor(connection) as cursor:
81
126
  cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
82
127
  result = cursor.fetchone() # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
83
- result = self.check_not_found(result) # pyright: ignore
128
+ result = self.check_not_found(result) # pyright: ignore
84
129
 
85
130
  column_names = [col[0] for col in cursor.description or []] # pyright: ignore[reportUnknownMemberType,reportUnknownVariableType]
86
131
  if schema_type is not None:
@@ -88,17 +133,40 @@ class DuckDBDriver(SyncDriverAdapterProtocol["DuckDBPyConnection"]):
88
133
  # Always return dictionaries
89
134
  return dict(zip(column_names, result)) # pyright: ignore[reportUnknownArgumentType,reportUnknownVariableType]
90
135
 
136
+ @overload
137
+ def select_one_or_none(
138
+ self,
139
+ sql: str,
140
+ parameters: "Optional[StatementParameterType]" = None,
141
+ /,
142
+ *,
143
+ connection: "Optional[DuckDBPyConnection]" = None,
144
+ schema_type: None = None,
145
+ **kwargs: Any,
146
+ ) -> "Optional[dict[str, Any]]": ...
147
+ @overload
148
+ def select_one_or_none(
149
+ self,
150
+ sql: str,
151
+ parameters: "Optional[StatementParameterType]" = None,
152
+ /,
153
+ *,
154
+ connection: "Optional[DuckDBPyConnection]" = None,
155
+ schema_type: "type[ModelDTOT]",
156
+ **kwargs: Any,
157
+ ) -> "Optional[ModelDTOT]": ...
91
158
  def select_one_or_none(
92
159
  self,
93
160
  sql: str,
94
161
  parameters: Optional["StatementParameterType"] = None,
95
162
  /,
163
+ *,
96
164
  connection: Optional["DuckDBPyConnection"] = None,
97
165
  schema_type: "Optional[type[ModelDTOT]]" = None,
166
+ **kwargs: Any,
98
167
  ) -> "Optional[Union[ModelDTOT, dict[str, Any]]]":
99
168
  connection = self._connection(connection)
100
- sql, parameters = self._process_sql_params(sql, parameters)
101
-
169
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
102
170
  with self._with_cursor(connection) as cursor:
103
171
  cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
104
172
  result = cursor.fetchone() # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
@@ -110,35 +178,82 @@ class DuckDBDriver(SyncDriverAdapterProtocol["DuckDBPyConnection"]):
110
178
  return cast("ModelDTOT", schema_type(**dict(zip(column_names, result)))) # pyright: ignore[reportUnknownArgumentType]
111
179
  return dict(zip(column_names, result)) # pyright: ignore[reportUnknownArgumentType,reportUnknownVariableType]
112
180
 
181
+ @overload
182
+ def select_value(
183
+ self,
184
+ sql: str,
185
+ parameters: "Optional[StatementParameterType]" = None,
186
+ /,
187
+ *,
188
+ connection: "Optional[DuckDBPyConnection]" = None,
189
+ schema_type: None = None,
190
+ **kwargs: Any,
191
+ ) -> "Any": ...
192
+ @overload
113
193
  def select_value(
114
194
  self,
115
195
  sql: str,
116
196
  parameters: "Optional[StatementParameterType]" = None,
117
197
  /,
198
+ *,
199
+ connection: "Optional[DuckDBPyConnection]" = None,
200
+ schema_type: "type[T]",
201
+ **kwargs: Any,
202
+ ) -> "T": ...
203
+ def select_value(
204
+ self,
205
+ sql: str,
206
+ parameters: "Optional[StatementParameterType]" = None,
207
+ /,
208
+ *,
118
209
  connection: "Optional[DuckDBPyConnection]" = None,
119
210
  schema_type: "Optional[type[T]]" = None,
211
+ **kwargs: Any,
120
212
  ) -> "Union[T, Any]":
121
213
  connection = self._connection(connection)
122
- sql, parameters = self._process_sql_params(sql, parameters)
123
-
214
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
124
215
  with self._with_cursor(connection) as cursor:
125
216
  cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
126
217
  result = cursor.fetchone() # pyright: ignore[reportUnknownMemberType,reportUnknownVariableType]
127
- result = self.check_not_found(result) # pyright: ignore
218
+ result = self.check_not_found(result) # pyright: ignore
128
219
  if schema_type is None:
129
220
  return result[0] # pyright: ignore
130
221
  return schema_type(result[0]) # type: ignore[call-arg]
131
222
 
223
+ @overload
132
224
  def select_value_or_none(
133
225
  self,
134
226
  sql: str,
135
227
  parameters: "Optional[StatementParameterType]" = None,
136
228
  /,
229
+ *,
230
+ connection: "Optional[DuckDBPyConnection]" = None,
231
+ schema_type: None = None,
232
+ **kwargs: Any,
233
+ ) -> "Optional[Any]": ...
234
+ @overload
235
+ def select_value_or_none(
236
+ self,
237
+ sql: str,
238
+ parameters: "Optional[StatementParameterType]" = None,
239
+ /,
240
+ *,
241
+ connection: "Optional[DuckDBPyConnection]" = None,
242
+ schema_type: "type[T]",
243
+ **kwargs: Any,
244
+ ) -> "Optional[T]": ...
245
+ def select_value_or_none(
246
+ self,
247
+ sql: str,
248
+ parameters: "Optional[StatementParameterType]" = None,
249
+ /,
250
+ *,
137
251
  connection: "Optional[DuckDBPyConnection]" = None,
138
252
  schema_type: "Optional[type[T]]" = None,
253
+ **kwargs: Any,
139
254
  ) -> "Optional[Union[T, Any]]":
140
255
  connection = self._connection(connection)
141
- sql, parameters = self._process_sql_params(sql, parameters)
256
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
142
257
  with self._with_cursor(connection) as cursor:
143
258
  cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
144
259
  result = cursor.fetchone() # pyright: ignore[reportUnknownMemberType,reportUnknownVariableType]
@@ -153,73 +268,88 @@ class DuckDBDriver(SyncDriverAdapterProtocol["DuckDBPyConnection"]):
153
268
  sql: str,
154
269
  parameters: Optional["StatementParameterType"] = None,
155
270
  /,
271
+ *,
156
272
  connection: Optional["DuckDBPyConnection"] = None,
273
+ **kwargs: Any,
157
274
  ) -> int:
158
275
  connection = self._connection(connection)
159
- sql, parameters = self._process_sql_params(sql, parameters)
276
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
160
277
  with self._with_cursor(connection) as cursor:
161
278
  cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
162
279
  return getattr(cursor, "rowcount", -1) # pyright: ignore[reportUnknownMemberType]
163
280
 
281
+ @overload
164
282
  def insert_update_delete_returning(
165
283
  self,
166
284
  sql: str,
167
- parameters: Optional["StatementParameterType"] = None,
285
+ parameters: "Optional[StatementParameterType]" = None,
168
286
  /,
169
- connection: Optional["DuckDBPyConnection"] = None,
287
+ *,
288
+ connection: "Optional[DuckDBPyConnection]" = None,
289
+ schema_type: None = None,
290
+ **kwargs: Any,
291
+ ) -> "dict[str, Any]": ...
292
+ @overload
293
+ def insert_update_delete_returning(
294
+ self,
295
+ sql: str,
296
+ parameters: "Optional[StatementParameterType]" = None,
297
+ /,
298
+ *,
299
+ connection: "Optional[DuckDBPyConnection]" = None,
300
+ schema_type: "type[ModelDTOT]",
301
+ **kwargs: Any,
302
+ ) -> "ModelDTOT": ...
303
+ def insert_update_delete_returning(
304
+ self,
305
+ sql: str,
306
+ parameters: "Optional[StatementParameterType]" = None,
307
+ /,
308
+ *,
309
+ connection: "Optional[DuckDBPyConnection]" = None,
170
310
  schema_type: "Optional[type[ModelDTOT]]" = None,
171
- ) -> "Optional[Union[dict[str, Any], ModelDTOT]]":
311
+ **kwargs: Any,
312
+ ) -> "Union[ModelDTOT, dict[str, Any]]":
172
313
  connection = self._connection(connection)
173
- sql, parameters = self._process_sql_params(sql, parameters)
314
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
174
315
  with self._with_cursor(connection) as cursor:
175
316
  cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
176
317
  result = cursor.fetchall() # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
177
- if not result:
178
- return None # pyright: ignore[reportUnknownArgumentType]
318
+ result = self.check_not_found(result) # pyright: ignore
179
319
  column_names = [col[0] for col in cursor.description or []] # pyright: ignore[reportUnknownMemberType,reportUnknownVariableType]
180
320
  if schema_type is not None:
181
321
  return cast("ModelDTOT", schema_type(**dict(zip(column_names, result[0])))) # pyright: ignore[reportUnknownArgumentType]
182
322
  # Always return dictionaries
183
323
  return dict(zip(column_names, result[0])) # pyright: ignore[reportUnknownArgumentType,reportUnknownVariableType]
184
324
 
185
- def _process_sql_params(
186
- self, sql: str, parameters: "Optional[StatementParameterType]" = None
187
- ) -> "tuple[str, Optional[Union[tuple[Any, ...], list[Any], dict[str, Any]]]]":
188
- """Process SQL query and parameters for DB-API execution.
189
-
190
- Converts named parameters (:name) to positional parameters (?) for DuckDB.
191
-
192
- Args:
193
- sql: The SQL query string.
194
- parameters: The parameters for the query (dict, tuple, list, or None).
195
-
196
- Returns:
197
- A tuple containing the processed SQL string and the processed parameters.
198
- """
199
- if not isinstance(parameters, dict) or not parameters:
200
- # If parameters are not a dict, or empty dict, assume positional/no params
201
- # Let the underlying driver handle tuples/lists directly
202
- return sql, parameters
203
-
204
- # Convert named parameters to positional parameters
205
- processed_sql = sql
206
- processed_params: list[Any] = []
207
- for key, value in parameters.items():
208
- # Replace :key with ? in the SQL
209
- processed_sql = processed_sql.replace(f":{key}", "?")
210
- processed_params.append(value)
211
-
212
- return processed_sql, tuple(processed_params)
213
-
214
325
  def execute_script(
215
326
  self,
216
327
  sql: str,
217
328
  parameters: Optional["StatementParameterType"] = None,
218
329
  /,
330
+ *,
219
331
  connection: Optional["DuckDBPyConnection"] = None,
332
+ **kwargs: Any,
220
333
  ) -> str:
221
334
  connection = self._connection(connection)
222
- sql, parameters = self._process_sql_params(sql, parameters)
335
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
223
336
  with self._with_cursor(connection) as cursor:
224
337
  cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
225
338
  return cast("str", getattr(cursor, "statusmessage", "DONE")) # pyright: ignore[reportUnknownMemberType]
339
+
340
+ # --- Arrow Bulk Operations ---
341
+
342
+ def select_arrow( # pyright: ignore[reportUnknownParameterType]
343
+ self,
344
+ sql: str,
345
+ parameters: "Optional[StatementParameterType]" = None,
346
+ /,
347
+ *,
348
+ connection: "Optional[DuckDBPyConnection]" = None,
349
+ **kwargs: Any,
350
+ ) -> "ArrowTable":
351
+ connection = self._connection(connection)
352
+ sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
353
+ with self._with_cursor(connection) as cursor:
354
+ cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
355
+ return cast("ArrowTable", cursor.fetch_arrow_table()) # pyright: ignore[reportUnknownMemberType]
@@ -1,16 +1,16 @@
1
1
  from sqlspec.adapters.oracledb.config import (
2
- OracleAsync,
3
- OracleAsyncPool,
4
- OracleSync,
5
- OracleSyncPool,
2
+ OracleAsyncConfig,
3
+ OracleAsyncPoolConfig,
4
+ OracleSyncConfig,
5
+ OracleSyncPoolConfig,
6
6
  )
7
7
  from sqlspec.adapters.oracledb.driver import OracleAsyncDriver, OracleSyncDriver
8
8
 
9
9
  __all__ = (
10
- "OracleAsync",
10
+ "OracleAsyncConfig",
11
11
  "OracleAsyncDriver",
12
- "OracleAsyncPool",
13
- "OracleSync",
12
+ "OracleAsyncPoolConfig",
13
+ "OracleSyncConfig",
14
14
  "OracleSyncDriver",
15
- "OracleSyncPool",
15
+ "OracleSyncPoolConfig",
16
16
  )
@@ -1,9 +1,9 @@
1
- from sqlspec.adapters.oracledb.config._asyncio import OracleAsync, OracleAsyncPool
2
- from sqlspec.adapters.oracledb.config._sync import OracleSync, OracleSyncPool
1
+ from sqlspec.adapters.oracledb.config._asyncio import OracleAsyncConfig, OracleAsyncPoolConfig
2
+ from sqlspec.adapters.oracledb.config._sync import OracleSyncConfig, OracleSyncPoolConfig
3
3
 
4
4
  __all__ = (
5
- "OracleAsync",
6
- "OracleAsyncPool",
7
- "OracleSync",
8
- "OracleSyncPool",
5
+ "OracleAsyncConfig",
6
+ "OracleAsyncPoolConfig",
7
+ "OracleSyncConfig",
8
+ "OracleSyncPoolConfig",
9
9
  )
@@ -1,6 +1,6 @@
1
1
  from contextlib import asynccontextmanager
2
2
  from dataclasses import dataclass, field
3
- from typing import TYPE_CHECKING, Any, Optional
3
+ from typing import TYPE_CHECKING, Any, Optional, cast
4
4
 
5
5
  from oracledb import create_pool_async as oracledb_create_pool # pyright: ignore[reportUnknownVariableType]
6
6
  from oracledb.connection import AsyncConnection
@@ -18,18 +18,18 @@ if TYPE_CHECKING:
18
18
 
19
19
 
20
20
  __all__ = (
21
- "OracleAsync",
22
- "OracleAsyncPool",
21
+ "OracleAsyncConfig",
22
+ "OracleAsyncPoolConfig",
23
23
  )
24
24
 
25
25
 
26
26
  @dataclass
27
- class OracleAsyncPool(OracleGenericPoolConfig["AsyncConnection", "AsyncConnectionPool"]):
27
+ class OracleAsyncPoolConfig(OracleGenericPoolConfig["AsyncConnection", "AsyncConnectionPool"]):
28
28
  """Async Oracle Pool Config"""
29
29
 
30
30
 
31
31
  @dataclass
32
- class OracleAsync(AsyncDatabaseConfig["AsyncConnection", "AsyncConnectionPool", "OracleAsyncDriver"]):
32
+ class OracleAsyncConfig(AsyncDatabaseConfig["AsyncConnection", "AsyncConnectionPool", "OracleAsyncDriver"]):
33
33
  """Oracle Async database Configuration.
34
34
 
35
35
  This class provides the base configuration for Oracle database connections, extending
@@ -42,7 +42,7 @@ class OracleAsync(AsyncDatabaseConfig["AsyncConnection", "AsyncConnectionPool",
42
42
  options.([2](https://python-oracledb.readthedocs.io/en/latest/user_guide/tuning.html))
43
43
  """
44
44
 
45
- pool_config: "Optional[OracleAsyncPool]" = None
45
+ pool_config: "Optional[OracleAsyncPoolConfig]" = None
46
46
  """Oracle Pool configuration"""
47
47
  pool_instance: "Optional[AsyncConnectionPool]" = None
48
48
  """Optional pool to use.
@@ -112,7 +112,7 @@ class OracleAsync(AsyncDatabaseConfig["AsyncConnection", "AsyncConnectionPool",
112
112
  raise ImproperConfigurationError(msg)
113
113
 
114
114
  async def create_connection(self) -> "AsyncConnection":
115
- """Create and return a new oracledb async connection.
115
+ """Create and return a new oracledb async connection from the pool.
116
116
 
117
117
  Returns:
118
118
  An AsyncConnection instance.
@@ -121,9 +121,8 @@ class OracleAsync(AsyncDatabaseConfig["AsyncConnection", "AsyncConnectionPool",
121
121
  ImproperConfigurationError: If the connection could not be created.
122
122
  """
123
123
  try:
124
- import oracledb
125
-
126
- return await oracledb.connect_async(**self.connection_config_dict) # type: ignore[no-any-return]
124
+ pool = await self.provide_pool()
125
+ return cast("AsyncConnection", await pool.acquire()) # type: ignore[no-any-return,unused-ignore]
127
126
  except Exception as e:
128
127
  msg = f"Could not configure the Oracle async connection. Error: {e!s}"
129
128
  raise ImproperConfigurationError(msg) from e
@@ -18,18 +18,18 @@ if TYPE_CHECKING:
18
18
 
19
19
 
20
20
  __all__ = (
21
- "OracleSync",
22
- "OracleSyncPool",
21
+ "OracleSyncConfig",
22
+ "OracleSyncPoolConfig",
23
23
  )
24
24
 
25
25
 
26
26
  @dataclass
27
- class OracleSyncPool(OracleGenericPoolConfig["Connection", "ConnectionPool"]):
27
+ class OracleSyncPoolConfig(OracleGenericPoolConfig["Connection", "ConnectionPool"]):
28
28
  """Sync Oracle Pool Config"""
29
29
 
30
30
 
31
31
  @dataclass
32
- class OracleSync(SyncDatabaseConfig["Connection", "ConnectionPool", "OracleSyncDriver"]):
32
+ class OracleSyncConfig(SyncDatabaseConfig["Connection", "ConnectionPool", "OracleSyncDriver"]):
33
33
  """Oracle Sync database Configuration.
34
34
 
35
35
  This class provides the base configuration for Oracle database connections, extending
@@ -42,7 +42,7 @@ class OracleSync(SyncDatabaseConfig["Connection", "ConnectionPool", "OracleSyncD
42
42
  options.([2](https://python-oracledb.readthedocs.io/en/latest/user_guide/tuning.html))
43
43
  """
44
44
 
45
- pool_config: "Optional[OracleSyncPool]" = None
45
+ pool_config: "Optional[OracleSyncPoolConfig]" = None
46
46
  """Oracle Pool configuration"""
47
47
  pool_instance: "Optional[ConnectionPool]" = None
48
48
  """Optional pool to use.
@@ -112,7 +112,7 @@ class OracleSync(SyncDatabaseConfig["Connection", "ConnectionPool", "OracleSyncD
112
112
  raise ImproperConfigurationError(msg)
113
113
 
114
114
  def create_connection(self) -> "Connection":
115
- """Create and return a new oracledb connection.
115
+ """Create and return a new oracledb connection from the pool.
116
116
 
117
117
  Returns:
118
118
  A Connection instance.
@@ -121,9 +121,8 @@ class OracleSync(SyncDatabaseConfig["Connection", "ConnectionPool", "OracleSyncD
121
121
  ImproperConfigurationError: If the connection could not be created.
122
122
  """
123
123
  try:
124
- import oracledb
125
-
126
- return oracledb.connect(**self.connection_config_dict)
124
+ pool = self.provide_pool()
125
+ return pool.acquire()
127
126
  except Exception as e:
128
127
  msg = f"Could not configure the Oracle connection. Error: {e!s}"
129
128
  raise ImproperConfigurationError(msg) from e