sqlspec 0.17.1__py3-none-any.whl → 0.18.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of sqlspec might be problematic. Click here for more details.

Files changed (75) hide show
  1. sqlspec/__init__.py +1 -1
  2. sqlspec/_sql.py +54 -159
  3. sqlspec/adapters/adbc/config.py +24 -30
  4. sqlspec/adapters/adbc/driver.py +42 -61
  5. sqlspec/adapters/aiosqlite/config.py +5 -10
  6. sqlspec/adapters/aiosqlite/driver.py +9 -25
  7. sqlspec/adapters/aiosqlite/pool.py +43 -35
  8. sqlspec/adapters/asyncmy/config.py +10 -7
  9. sqlspec/adapters/asyncmy/driver.py +18 -39
  10. sqlspec/adapters/asyncpg/config.py +4 -0
  11. sqlspec/adapters/asyncpg/driver.py +32 -79
  12. sqlspec/adapters/bigquery/config.py +12 -65
  13. sqlspec/adapters/bigquery/driver.py +39 -133
  14. sqlspec/adapters/duckdb/config.py +11 -15
  15. sqlspec/adapters/duckdb/driver.py +61 -85
  16. sqlspec/adapters/duckdb/pool.py +2 -5
  17. sqlspec/adapters/oracledb/_types.py +8 -1
  18. sqlspec/adapters/oracledb/config.py +55 -38
  19. sqlspec/adapters/oracledb/driver.py +35 -92
  20. sqlspec/adapters/oracledb/migrations.py +257 -0
  21. sqlspec/adapters/psqlpy/config.py +13 -9
  22. sqlspec/adapters/psqlpy/driver.py +28 -103
  23. sqlspec/adapters/psycopg/config.py +9 -5
  24. sqlspec/adapters/psycopg/driver.py +107 -175
  25. sqlspec/adapters/sqlite/config.py +7 -5
  26. sqlspec/adapters/sqlite/driver.py +37 -73
  27. sqlspec/adapters/sqlite/pool.py +3 -12
  28. sqlspec/base.py +1 -8
  29. sqlspec/builder/__init__.py +1 -1
  30. sqlspec/builder/_base.py +34 -20
  31. sqlspec/builder/_ddl.py +407 -183
  32. sqlspec/builder/_insert.py +1 -1
  33. sqlspec/builder/mixins/_insert_operations.py +26 -6
  34. sqlspec/builder/mixins/_merge_operations.py +1 -1
  35. sqlspec/builder/mixins/_select_operations.py +1 -5
  36. sqlspec/config.py +32 -13
  37. sqlspec/core/__init__.py +89 -14
  38. sqlspec/core/cache.py +57 -104
  39. sqlspec/core/compiler.py +57 -112
  40. sqlspec/core/filters.py +1 -21
  41. sqlspec/core/hashing.py +13 -47
  42. sqlspec/core/parameters.py +272 -261
  43. sqlspec/core/result.py +12 -27
  44. sqlspec/core/splitter.py +17 -21
  45. sqlspec/core/statement.py +150 -159
  46. sqlspec/driver/_async.py +2 -15
  47. sqlspec/driver/_common.py +16 -95
  48. sqlspec/driver/_sync.py +2 -15
  49. sqlspec/driver/mixins/_result_tools.py +8 -29
  50. sqlspec/driver/mixins/_sql_translator.py +6 -8
  51. sqlspec/exceptions.py +1 -2
  52. sqlspec/loader.py +43 -115
  53. sqlspec/migrations/__init__.py +1 -1
  54. sqlspec/migrations/base.py +34 -45
  55. sqlspec/migrations/commands.py +34 -15
  56. sqlspec/migrations/loaders.py +1 -1
  57. sqlspec/migrations/runner.py +104 -19
  58. sqlspec/migrations/tracker.py +49 -2
  59. sqlspec/protocols.py +3 -6
  60. sqlspec/storage/__init__.py +4 -4
  61. sqlspec/storage/backends/fsspec.py +5 -6
  62. sqlspec/storage/backends/obstore.py +7 -8
  63. sqlspec/storage/registry.py +3 -3
  64. sqlspec/utils/__init__.py +2 -2
  65. sqlspec/utils/logging.py +6 -10
  66. sqlspec/utils/sync_tools.py +27 -4
  67. sqlspec/utils/text.py +6 -1
  68. {sqlspec-0.17.1.dist-info → sqlspec-0.18.0.dist-info}/METADATA +1 -1
  69. sqlspec-0.18.0.dist-info/RECORD +138 -0
  70. sqlspec/builder/_ddl_utils.py +0 -103
  71. sqlspec-0.17.1.dist-info/RECORD +0 -138
  72. {sqlspec-0.17.1.dist-info → sqlspec-0.18.0.dist-info}/WHEEL +0 -0
  73. {sqlspec-0.17.1.dist-info → sqlspec-0.18.0.dist-info}/entry_points.txt +0 -0
  74. {sqlspec-0.17.1.dist-info → sqlspec-0.18.0.dist-info}/licenses/LICENSE +0 -0
  75. {sqlspec-0.17.1.dist-info → sqlspec-0.18.0.dist-info}/licenses/NOTICE +0 -0
@@ -1,17 +1,15 @@
1
- """Enhanced DuckDB driver with CORE_ROUND_3 architecture integration.
2
-
3
- This driver implements the complete CORE_ROUND_3 architecture for:
4
- - 5-10x faster SQL compilation through single-pass processing
5
- - 40-60% memory reduction through __slots__ optimization
6
- - Enhanced caching for repeated statement execution
7
- - Complete backward compatibility with existing functionality
8
-
9
- Architecture Features:
10
- - Direct integration with sqlspec.core modules
11
- - Enhanced parameter processing with type coercion
12
- - DuckDB-optimized resource management
13
- - MyPyC-optimized performance patterns
14
- - Zero-copy data access where possible
1
+ """DuckDB driver implementation.
2
+
3
+ This driver provides:
4
+ - SQL compilation with single-pass processing
5
+ - Memory-efficient design with __slots__
6
+ - Statement caching for repeated execution
7
+ - Backward compatibility with existing functionality
8
+
9
+ Features:
10
+ - Integration with sqlspec.core modules
11
+ - Parameter processing with type coercion
12
+ - DuckDB resource management
15
13
  - Multi-parameter style support
16
14
  """
17
15
 
@@ -38,37 +36,32 @@ __all__ = ("DuckDBCursor", "DuckDBDriver", "DuckDBExceptionHandler", "duckdb_sta
38
36
 
39
37
  logger = get_logger("adapters.duckdb")
40
38
 
41
- # Enhanced DuckDB statement configuration using core modules with performance optimizations
39
+
42
40
  duckdb_statement_config = StatementConfig(
43
41
  dialect="duckdb",
44
42
  parameter_config=ParameterStyleConfig(
45
43
  default_parameter_style=ParameterStyle.QMARK,
46
44
  supported_parameter_styles={ParameterStyle.QMARK, ParameterStyle.NUMERIC, ParameterStyle.NAMED_DOLLAR},
47
45
  default_execution_parameter_style=ParameterStyle.QMARK,
48
- supported_execution_parameter_styles={
49
- ParameterStyle.QMARK,
50
- ParameterStyle.NUMERIC,
51
- ParameterStyle.NAMED_DOLLAR,
52
- },
46
+ supported_execution_parameter_styles={ParameterStyle.QMARK, ParameterStyle.NUMERIC},
53
47
  type_coercion_map={},
54
48
  has_native_list_expansion=True,
55
49
  needs_static_script_compilation=False,
56
50
  preserve_parameter_format=True,
57
- allow_mixed_parameter_styles=False, # DuckDB doesn't support mixed styles in single statement
51
+ allow_mixed_parameter_styles=False,
58
52
  ),
59
- # Core processing features enabled for performance
60
53
  enable_parsing=True,
61
54
  enable_validation=True,
62
55
  enable_caching=True,
63
56
  enable_parameter_type_wrapping=True,
64
57
  )
65
58
 
66
- # DuckDB operation detection constants
59
+
67
60
  MODIFYING_OPERATIONS: Final[tuple[str, ...]] = ("INSERT", "UPDATE", "DELETE")
68
61
 
69
62
 
70
63
  class DuckDBCursor:
71
- """Context manager for DuckDB cursor management with enhanced error handling."""
64
+ """Context manager for DuckDB cursor management."""
72
65
 
73
66
  __slots__ = ("connection", "cursor")
74
67
 
@@ -81,7 +74,7 @@ class DuckDBCursor:
81
74
  return self.cursor
82
75
 
83
76
  def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
84
- _ = (exc_type, exc_val, exc_tb) # Mark as intentionally unused
77
+ _ = (exc_type, exc_val, exc_tb)
85
78
  if self.cursor is not None:
86
79
  self.cursor.close()
87
80
 
@@ -133,34 +126,33 @@ class DuckDBExceptionHandler:
133
126
 
134
127
 
135
128
  class DuckDBDriver(SyncDriverAdapterBase):
136
- """Enhanced DuckDB driver with CORE_ROUND_3 architecture integration.
129
+ """DuckDB driver implementation.
137
130
 
138
- This driver leverages the complete core module system for maximum performance:
131
+ This driver uses the core module system for SQL processing:
139
132
 
140
- Performance Improvements:
141
- - 5-10x faster SQL compilation through single-pass processing
142
- - 40-60% memory reduction through __slots__ optimization
143
- - Enhanced caching for repeated statement execution
144
- - Zero-copy parameter processing where possible
145
- - DuckDB-optimized resource management
133
+ Features:
134
+ - SQL compilation with single-pass processing
135
+ - Memory-efficient design with __slots__
136
+ - Statement caching for repeated execution
137
+ - Parameter processing with type coercion
138
+ - DuckDB resource management
146
139
 
147
- Core Integration Features:
148
- - sqlspec.core.statement for enhanced SQL processing
149
- - sqlspec.core.parameters for optimized parameter handling
150
- - sqlspec.core.cache for unified statement caching
151
- - sqlspec.core.config for centralized configuration management
140
+ Core Integration:
141
+ - sqlspec.core.statement for SQL processing
142
+ - sqlspec.core.parameters for parameter handling
143
+ - sqlspec.core.cache for statement caching
144
+ - sqlspec.core.config for configuration management
152
145
 
153
- DuckDB Features:
146
+ DuckDB Support:
154
147
  - Multi-parameter style support (QMARK, NUMERIC, NAMED_DOLLAR)
155
- - Enhanced script execution with statement splitting
156
- - Optimized batch operations with accurate row counting
148
+ - Script execution with statement splitting
149
+ - Batch operations with row counting
157
150
  - DuckDB-specific exception handling
158
151
 
159
152
  Compatibility:
160
- - 100% backward compatibility with existing DuckDB driver interface
161
- - All existing tests pass without modification
162
- - Complete StatementConfig API compatibility
163
- - Preserved transaction management patterns
153
+ - Backward compatibility with existing DuckDB driver interface
154
+ - StatementConfig API compatibility
155
+ - Transaction management patterns
164
156
  """
165
157
 
166
158
  __slots__ = ()
@@ -172,21 +164,20 @@ class DuckDBDriver(SyncDriverAdapterBase):
172
164
  statement_config: "Optional[StatementConfig]" = None,
173
165
  driver_features: "Optional[dict[str, Any]]" = None,
174
166
  ) -> None:
175
- # Enhanced configuration with global settings integration
176
167
  if statement_config is None:
177
168
  cache_config = get_cache_config()
178
- enhanced_config = duckdb_statement_config.replace(
169
+ updated_config = duckdb_statement_config.replace(
179
170
  enable_caching=cache_config.compiled_cache_enabled,
180
- enable_parsing=True, # Default to enabled
181
- enable_validation=True, # Default to enabled
182
- dialect="duckdb", # Use adapter-specific dialect
171
+ enable_parsing=True,
172
+ enable_validation=True,
173
+ dialect="duckdb",
183
174
  )
184
- statement_config = enhanced_config
175
+ statement_config = updated_config
185
176
 
186
177
  super().__init__(connection=connection, statement_config=statement_config, driver_features=driver_features)
187
178
 
188
179
  def with_cursor(self, connection: "DuckDBConnection") -> "DuckDBCursor":
189
- """Create context manager for DuckDB cursor with enhanced resource management."""
180
+ """Create context manager for DuckDB cursor."""
190
181
  return DuckDBCursor(connection)
191
182
 
192
183
  def handle_database_exceptions(self) -> "AbstractContextManager[None]":
@@ -206,14 +197,14 @@ class DuckDBDriver(SyncDriverAdapterBase):
206
197
  Returns:
207
198
  None for standard execution (no special operations)
208
199
  """
209
- _ = (cursor, statement) # Mark as intentionally unused
200
+ _ = (cursor, statement)
210
201
  return None
211
202
 
212
203
  def _is_modifying_operation(self, statement: SQL) -> bool:
213
- """Check if the SQL statement is a modifying operation using enhanced detection.
204
+ """Check if the SQL statement is a modifying operation.
214
205
 
215
206
  Uses both AST-based detection (when available) and SQL text analysis
216
- for comprehensive operation type identification.
207
+ to identify operation type.
217
208
 
218
209
  Args:
219
210
  statement: SQL statement to analyze
@@ -221,20 +212,19 @@ class DuckDBDriver(SyncDriverAdapterBase):
221
212
  Returns:
222
213
  True if the operation modifies data (INSERT/UPDATE/DELETE)
223
214
  """
224
- # Enhanced AST-based detection using core expression
215
+
225
216
  expression = statement.expression
226
217
  if expression and isinstance(expression, (exp.Insert, exp.Update, exp.Delete)):
227
218
  return True
228
219
 
229
- # Fallback to SQL text analysis for comprehensive detection
230
220
  sql_upper = statement.sql.strip().upper()
231
221
  return any(sql_upper.startswith(op) for op in MODIFYING_OPERATIONS)
232
222
 
233
223
  def _execute_script(self, cursor: Any, statement: SQL) -> "ExecutionResult":
234
- """Execute SQL script using enhanced statement splitting and parameter handling.
224
+ """Execute SQL script with statement splitting and parameter handling.
235
225
 
236
- Uses core module optimization for statement parsing and parameter processing.
237
- Handles DuckDB-specific script execution requirements with parameter support.
226
+ Uses core module for statement parsing and parameter processing.
227
+ Handles DuckDB script execution requirements with parameter support.
238
228
 
239
229
  Args:
240
230
  cursor: DuckDB cursor object
@@ -250,7 +240,6 @@ class DuckDBDriver(SyncDriverAdapterBase):
250
240
  last_result = None
251
241
 
252
242
  for stmt in statements:
253
- # Execute each statement with parameters (DuckDB supports parameters in script statements)
254
243
  last_result = cursor.execute(stmt, prepared_parameters or ())
255
244
  successful_count += 1
256
245
 
@@ -259,35 +248,30 @@ class DuckDBDriver(SyncDriverAdapterBase):
259
248
  )
260
249
 
261
250
  def _execute_many(self, cursor: Any, statement: SQL) -> "ExecutionResult":
262
- """Execute SQL with multiple parameter sets using optimized batch processing.
251
+ """Execute SQL with multiple parameter sets using batch processing.
263
252
 
264
- Leverages DuckDB's executemany for efficient batch operations with
265
- enhanced row counting for both modifying and non-modifying operations.
253
+ Uses DuckDB's executemany for batch operations with
254
+ row counting for both modifying and non-modifying operations.
266
255
 
267
256
  Args:
268
257
  cursor: DuckDB cursor object
269
258
  statement: SQL statement with multiple parameter sets
270
259
 
271
260
  Returns:
272
- ExecutionResult with accurate batch execution metadata
261
+ ExecutionResult with batch execution metadata
273
262
  """
274
263
  sql, prepared_parameters = self._get_compiled_sql(statement, self.statement_config)
275
264
 
276
265
  if prepared_parameters:
277
- # Use DuckDB's efficient executemany for batch operations
278
266
  cursor.executemany(sql, prepared_parameters)
279
267
 
280
- # Enhanced row counting based on operation type
281
268
  if self._is_modifying_operation(statement):
282
- # For modifying operations, count equals number of parameter sets
283
269
  row_count = len(prepared_parameters)
284
270
  else:
285
- # For non-modifying operations, attempt to fetch result count
286
271
  try:
287
272
  result = cursor.fetchone()
288
273
  row_count = int(result[0]) if result and isinstance(result, tuple) and len(result) == 1 else 0
289
274
  except Exception:
290
- # Fallback to cursor.rowcount or 0
291
275
  row_count = max(cursor.rowcount, 0) if hasattr(cursor, "rowcount") else 0
292
276
  else:
293
277
  row_count = 0
@@ -295,32 +279,28 @@ class DuckDBDriver(SyncDriverAdapterBase):
295
279
  return self.create_execution_result(cursor, rowcount_override=row_count, is_many_result=True)
296
280
 
297
281
  def _execute_statement(self, cursor: Any, statement: SQL) -> "ExecutionResult":
298
- """Execute single SQL statement with enhanced data handling and performance optimization.
282
+ """Execute single SQL statement with data handling.
299
283
 
300
- Uses core processing for optimal parameter handling and result processing.
301
- Handles both SELECT queries and non-SELECT operations efficiently.
284
+ Uses core processing for parameter handling and result processing.
285
+ Handles both SELECT queries and non-SELECT operations.
302
286
 
303
287
  Args:
304
288
  cursor: DuckDB cursor object
305
289
  statement: SQL statement to execute
306
290
 
307
291
  Returns:
308
- ExecutionResult with comprehensive execution metadata
292
+ ExecutionResult with execution metadata
309
293
  """
310
294
  sql, prepared_parameters = self._get_compiled_sql(statement, self.statement_config)
311
295
  cursor.execute(sql, prepared_parameters or ())
312
296
 
313
- # Enhanced SELECT result processing
314
297
  if statement.returns_rows():
315
298
  fetched_data = cursor.fetchall()
316
299
  column_names = [col[0] for col in cursor.description or []]
317
300
 
318
- # Efficient data conversion handling multiple formats
319
301
  if fetched_data and isinstance(fetched_data[0], tuple):
320
- # Convert tuple rows to dictionaries for consistent interface
321
302
  dict_data = [dict(zip(column_names, row)) for row in fetched_data]
322
303
  else:
323
- # Data already in appropriate format
324
304
  dict_data = fetched_data
325
305
 
326
306
  return self.create_execution_result(
@@ -331,20 +311,16 @@ class DuckDBDriver(SyncDriverAdapterBase):
331
311
  is_select_result=True,
332
312
  )
333
313
 
334
- # Enhanced non-SELECT result processing with multiple row count strategies
335
314
  try:
336
- # Try to fetch result for operations that return row counts
337
315
  result = cursor.fetchone()
338
316
  row_count = int(result[0]) if result and isinstance(result, tuple) and len(result) == 1 else 0
339
317
  except Exception:
340
- # Fallback to cursor.rowcount or 0 for operations without result sets
341
318
  row_count = max(cursor.rowcount, 0) if hasattr(cursor, "rowcount") else 0
342
319
 
343
320
  return self.create_execution_result(cursor, rowcount_override=row_count)
344
321
 
345
- # Transaction management with enhanced error handling
346
322
  def begin(self) -> None:
347
- """Begin a database transaction with enhanced error handling."""
323
+ """Begin a database transaction."""
348
324
  try:
349
325
  self.connection.execute("BEGIN TRANSACTION")
350
326
  except duckdb.Error as e:
@@ -352,7 +328,7 @@ class DuckDBDriver(SyncDriverAdapterBase):
352
328
  raise SQLSpecError(msg) from e
353
329
 
354
330
  def rollback(self) -> None:
355
- """Rollback the current transaction with enhanced error handling."""
331
+ """Rollback the current transaction."""
356
332
  try:
357
333
  self.connection.rollback()
358
334
  except duckdb.Error as e:
@@ -360,7 +336,7 @@ class DuckDBDriver(SyncDriverAdapterBase):
360
336
  raise SQLSpecError(msg) from e
361
337
 
362
338
  def commit(self) -> None:
363
- """Commit the current transaction with enhanced error handling."""
339
+ """Commit the current transaction."""
364
340
  try:
365
341
  self.connection.commit()
366
342
  except duckdb.Error as e:
@@ -25,7 +25,7 @@ __all__ = ("DuckDBConnectionPool",)
25
25
 
26
26
 
27
27
  class DuckDBConnectionPool:
28
- """Thread-local connection manager for DuckDB with performance optimizations.
28
+ """Thread-local connection manager for DuckDB.
29
29
 
30
30
  Uses thread-local storage to ensure each thread gets its own DuckDB connection,
31
31
  preventing the thread-safety issues that cause segmentation faults when
@@ -54,7 +54,7 @@ class DuckDBConnectionPool:
54
54
  extensions: "Optional[list[dict[str, Any]]]" = None,
55
55
  secrets: "Optional[list[dict[str, Any]]]" = None,
56
56
  on_connection_create: "Optional[Callable[[DuckDBConnection], None]]" = None,
57
- **kwargs: Any, # Accept and ignore additional parameters for compatibility
57
+ **kwargs: Any,
58
58
  ) -> None:
59
59
  """Initialize the thread-local connection manager.
60
60
 
@@ -159,7 +159,6 @@ class DuckDBConnectionPool:
159
159
  self._thread_local.connection = self._create_connection()
160
160
  self._thread_local.created_at = time.time()
161
161
 
162
- # Check if connection needs recycling
163
162
  if self._recycle > 0 and time.time() - self._thread_local.created_at > self._recycle:
164
163
  with suppress(Exception):
165
164
  self._thread_local.connection.close()
@@ -207,7 +206,6 @@ class DuckDBConnectionPool:
207
206
  try:
208
207
  yield connection
209
208
  except Exception:
210
- # On error, close and recreate connection for this thread
211
209
  self._close_thread_connection()
212
210
  raise
213
211
 
@@ -240,4 +238,3 @@ class DuckDBConnectionPool:
240
238
  Args:
241
239
  connection: The connection to release (ignored)
242
240
  """
243
- # No-op: thread-local connections are managed per-thread
@@ -3,12 +3,19 @@ from typing import TYPE_CHECKING
3
3
  from oracledb import AsyncConnection, Connection
4
4
 
5
5
  if TYPE_CHECKING:
6
+ from oracledb.pool import AsyncConnectionPool, ConnectionPool
6
7
  from typing_extensions import TypeAlias
7
8
 
8
9
  OracleSyncConnection: TypeAlias = Connection
9
10
  OracleAsyncConnection: TypeAlias = AsyncConnection
11
+ OracleSyncConnectionPool: TypeAlias = ConnectionPool
12
+ OracleAsyncConnectionPool: TypeAlias = AsyncConnectionPool
10
13
  else:
14
+ from oracledb.pool import AsyncConnectionPool, ConnectionPool
15
+
11
16
  OracleSyncConnection = Connection
12
17
  OracleAsyncConnection = AsyncConnection
18
+ OracleSyncConnectionPool = ConnectionPool
19
+ OracleAsyncConnectionPool = AsyncConnectionPool
13
20
 
14
- __all__ = ("OracleAsyncConnection", "OracleSyncConnection")
21
+ __all__ = ("OracleAsyncConnection", "OracleAsyncConnectionPool", "OracleSyncConnection", "OracleSyncConnectionPool")
@@ -8,7 +8,12 @@ from typing import TYPE_CHECKING, Any, ClassVar, Optional, TypedDict, Union, cas
8
8
  import oracledb
9
9
  from typing_extensions import NotRequired
10
10
 
11
- from sqlspec.adapters.oracledb._types import OracleAsyncConnection, OracleSyncConnection
11
+ from sqlspec.adapters.oracledb._types import (
12
+ OracleAsyncConnection,
13
+ OracleAsyncConnectionPool,
14
+ OracleSyncConnection,
15
+ OracleSyncConnectionPool,
16
+ )
12
17
  from sqlspec.adapters.oracledb.driver import (
13
18
  OracleAsyncCursor,
14
19
  OracleAsyncDriver,
@@ -16,13 +21,13 @@ from sqlspec.adapters.oracledb.driver import (
16
21
  OracleSyncDriver,
17
22
  oracledb_statement_config,
18
23
  )
24
+ from sqlspec.adapters.oracledb.migrations import OracleAsyncMigrationTracker, OracleSyncMigrationTracker
19
25
  from sqlspec.config import AsyncDatabaseConfig, SyncDatabaseConfig
20
26
 
21
27
  if TYPE_CHECKING:
22
28
  from collections.abc import AsyncGenerator, Callable, Generator
23
29
 
24
30
  from oracledb import AuthMode
25
- from oracledb.pool import AsyncConnectionPool, ConnectionPool
26
31
 
27
32
  from sqlspec.core.statement import StatementConfig
28
33
 
@@ -72,29 +77,34 @@ class OraclePoolParams(OracleConnectionParams, total=False):
72
77
  extra: NotRequired[dict[str, Any]]
73
78
 
74
79
 
75
- class OracleSyncConfig(SyncDatabaseConfig[OracleSyncConnection, "ConnectionPool", OracleSyncDriver]):
76
- """Configuration for Oracle synchronous database connections with direct field-based configuration."""
80
+ class OracleSyncConfig(SyncDatabaseConfig[OracleSyncConnection, "OracleSyncConnectionPool", OracleSyncDriver]):
81
+ """Configuration for Oracle synchronous database connections."""
82
+
83
+ __slots__ = ()
77
84
 
78
85
  driver_type: ClassVar[type[OracleSyncDriver]] = OracleSyncDriver
79
86
  connection_type: "ClassVar[type[OracleSyncConnection]]" = OracleSyncConnection
87
+ migration_tracker_type: "ClassVar[type[OracleSyncMigrationTracker]]" = OracleSyncMigrationTracker
80
88
 
81
89
  def __init__(
82
90
  self,
83
91
  *,
84
- pool_instance: "Optional[ConnectionPool]" = None,
85
92
  pool_config: "Optional[Union[OraclePoolParams, dict[str, Any]]]" = None,
86
- statement_config: "Optional[StatementConfig]" = None,
93
+ pool_instance: "Optional[OracleSyncConnectionPool]" = None,
87
94
  migration_config: Optional[dict[str, Any]] = None,
95
+ statement_config: "Optional[StatementConfig]" = None,
96
+ driver_features: "Optional[dict[str, Any]]" = None,
88
97
  ) -> None:
89
98
  """Initialize Oracle synchronous configuration.
90
99
 
91
100
  Args:
92
101
  pool_config: Pool configuration parameters
93
102
  pool_instance: Existing pool instance to use
94
- statement_config: Default SQL statement configuration
95
103
  migration_config: Migration configuration
104
+ statement_config: Default SQL statement configuration
105
+ driver_features: Optional driver feature configuration
96
106
  """
97
- # Store the pool config as a dict and extract/merge extras
107
+
98
108
  processed_pool_config: dict[str, Any] = dict(pool_config) if pool_config else {}
99
109
  if "extra" in processed_pool_config:
100
110
  extras = processed_pool_config.pop("extra")
@@ -105,9 +115,10 @@ class OracleSyncConfig(SyncDatabaseConfig[OracleSyncConnection, "ConnectionPool"
105
115
  pool_instance=pool_instance,
106
116
  migration_config=migration_config,
107
117
  statement_config=statement_config,
118
+ driver_features=driver_features or {},
108
119
  )
109
120
 
110
- def _create_pool(self) -> "ConnectionPool":
121
+ def _create_pool(self) -> "OracleSyncConnectionPool":
111
122
  """Create the actual connection pool."""
112
123
 
113
124
  return oracledb.create_pool(**dict(self.pool_config))
@@ -128,13 +139,9 @@ class OracleSyncConfig(SyncDatabaseConfig[OracleSyncConnection, "ConnectionPool"
128
139
  return self.pool_instance.acquire()
129
140
 
130
141
  @contextlib.contextmanager
131
- def provide_connection(self, *args: Any, **kwargs: Any) -> "Generator[OracleSyncConnection, None, None]":
142
+ def provide_connection(self) -> "Generator[OracleSyncConnection, None, None]":
132
143
  """Provide a connection context manager.
133
144
 
134
- Args:
135
- *args: Additional arguments.
136
- **kwargs: Additional keyword arguments.
137
-
138
145
  Yields:
139
146
  An Oracle Connection instance.
140
147
  """
@@ -153,17 +160,18 @@ class OracleSyncConfig(SyncDatabaseConfig[OracleSyncConnection, "ConnectionPool"
153
160
  """Provide a driver session context manager.
154
161
 
155
162
  Args:
156
- *args: Additional arguments.
163
+ *args: Positional arguments (unused).
157
164
  statement_config: Optional statement configuration override.
158
- **kwargs: Additional keyword arguments.
165
+ **kwargs: Keyword arguments (unused).
159
166
 
160
167
  Yields:
161
168
  An OracleSyncDriver instance.
162
169
  """
163
- with self.provide_connection(*args, **kwargs) as conn:
170
+ _ = (args, kwargs) # Mark as intentionally unused
171
+ with self.provide_connection() as conn:
164
172
  yield self.driver_type(connection=conn, statement_config=statement_config or self.statement_config)
165
173
 
166
- def provide_pool(self, *args: Any, **kwargs: Any) -> "ConnectionPool":
174
+ def provide_pool(self) -> "OracleSyncConnectionPool":
167
175
  """Provide pool instance.
168
176
 
169
177
  Returns:
@@ -176,8 +184,7 @@ class OracleSyncConfig(SyncDatabaseConfig[OracleSyncConnection, "ConnectionPool"
176
184
  def get_signature_namespace(self) -> "dict[str, type[Any]]":
177
185
  """Get the signature namespace for OracleDB types.
178
186
 
179
- This provides all OracleDB-specific types that Litestar needs to recognize
180
- to avoid serialization attempts.
187
+ Provides OracleDB-specific types for Litestar framework recognition.
181
188
 
182
189
  Returns:
183
190
  Dictionary mapping type names to types.
@@ -188,35 +195,42 @@ class OracleSyncConfig(SyncDatabaseConfig[OracleSyncConnection, "ConnectionPool"
188
195
  {
189
196
  "OracleSyncConnection": OracleSyncConnection,
190
197
  "OracleAsyncConnection": OracleAsyncConnection,
198
+ "OracleSyncConnectionPool": OracleSyncConnectionPool,
199
+ "OracleAsyncConnectionPool": OracleAsyncConnectionPool,
191
200
  "OracleSyncCursor": OracleSyncCursor,
192
201
  }
193
202
  )
194
203
  return namespace
195
204
 
196
205
 
197
- class OracleAsyncConfig(AsyncDatabaseConfig[OracleAsyncConnection, "AsyncConnectionPool", OracleAsyncDriver]):
198
- """Configuration for Oracle asynchronous database connections with direct field-based configuration."""
206
+ class OracleAsyncConfig(AsyncDatabaseConfig[OracleAsyncConnection, "OracleAsyncConnectionPool", OracleAsyncDriver]):
207
+ """Configuration for Oracle asynchronous database connections."""
208
+
209
+ __slots__ = ()
199
210
 
200
211
  connection_type: "ClassVar[type[OracleAsyncConnection]]" = OracleAsyncConnection
201
212
  driver_type: ClassVar[type[OracleAsyncDriver]] = OracleAsyncDriver
213
+ migration_tracker_type: "ClassVar[type[OracleAsyncMigrationTracker]]" = OracleAsyncMigrationTracker
202
214
 
203
215
  def __init__(
204
216
  self,
205
217
  *,
206
218
  pool_config: "Optional[Union[OraclePoolParams, dict[str, Any]]]" = None,
207
- pool_instance: "Optional[AsyncConnectionPool]" = None,
208
- statement_config: "Optional[StatementConfig]" = None,
219
+ pool_instance: "Optional[OracleAsyncConnectionPool]" = None,
209
220
  migration_config: Optional[dict[str, Any]] = None,
221
+ statement_config: "Optional[StatementConfig]" = None,
222
+ driver_features: "Optional[dict[str, Any]]" = None,
210
223
  ) -> None:
211
224
  """Initialize Oracle asynchronous configuration.
212
225
 
213
226
  Args:
214
227
  pool_config: Pool configuration parameters
215
228
  pool_instance: Existing pool instance to use
216
- statement_config: Default SQL statement configuration
217
229
  migration_config: Migration configuration
230
+ statement_config: Default SQL statement configuration
231
+ driver_features: Optional driver feature configuration
218
232
  """
219
- # Store the pool config as a dict and extract/merge extras
233
+
220
234
  processed_pool_config: dict[str, Any] = dict(pool_config) if pool_config else {}
221
235
  if "extra" in processed_pool_config:
222
236
  extras = processed_pool_config.pop("extra")
@@ -227,9 +241,10 @@ class OracleAsyncConfig(AsyncDatabaseConfig[OracleAsyncConnection, "AsyncConnect
227
241
  pool_instance=pool_instance,
228
242
  migration_config=migration_config,
229
243
  statement_config=statement_config or oracledb_statement_config,
244
+ driver_features=driver_features or {},
230
245
  )
231
246
 
232
- async def _create_pool(self) -> "AsyncConnectionPool":
247
+ async def _create_pool(self) -> "OracleAsyncConnectionPool":
233
248
  """Create the actual async connection pool."""
234
249
 
235
250
  return oracledb.create_pool_async(**dict(self.pool_config))
@@ -239,6 +254,10 @@ class OracleAsyncConfig(AsyncDatabaseConfig[OracleAsyncConnection, "AsyncConnect
239
254
  if self.pool_instance:
240
255
  await self.pool_instance.close()
241
256
 
257
+ async def close_pool(self) -> None:
258
+ """Close the connection pool."""
259
+ await self._close_pool()
260
+
242
261
  async def create_connection(self) -> OracleAsyncConnection:
243
262
  """Create a single async connection (not from pool).
244
263
 
@@ -250,13 +269,9 @@ class OracleAsyncConfig(AsyncDatabaseConfig[OracleAsyncConnection, "AsyncConnect
250
269
  return cast("OracleAsyncConnection", await self.pool_instance.acquire())
251
270
 
252
271
  @asynccontextmanager
253
- async def provide_connection(self, *args: Any, **kwargs: Any) -> "AsyncGenerator[OracleAsyncConnection, None]":
272
+ async def provide_connection(self) -> "AsyncGenerator[OracleAsyncConnection, None]":
254
273
  """Provide an async connection context manager.
255
274
 
256
- Args:
257
- *args: Additional arguments.
258
- **kwargs: Additional keyword arguments.
259
-
260
275
  Yields:
261
276
  An Oracle AsyncConnection instance.
262
277
  """
@@ -275,17 +290,18 @@ class OracleAsyncConfig(AsyncDatabaseConfig[OracleAsyncConnection, "AsyncConnect
275
290
  """Provide an async driver session context manager.
276
291
 
277
292
  Args:
278
- *args: Additional arguments.
293
+ *args: Positional arguments (unused).
279
294
  statement_config: Optional statement configuration override.
280
- **kwargs: Additional keyword arguments.
295
+ **kwargs: Keyword arguments (unused).
281
296
 
282
297
  Yields:
283
298
  An OracleAsyncDriver instance.
284
299
  """
285
- async with self.provide_connection(*args, **kwargs) as conn:
300
+ _ = (args, kwargs) # Mark as intentionally unused
301
+ async with self.provide_connection() as conn:
286
302
  yield self.driver_type(connection=conn, statement_config=statement_config or self.statement_config)
287
303
 
288
- async def provide_pool(self, *args: Any, **kwargs: Any) -> "AsyncConnectionPool":
304
+ async def provide_pool(self) -> "OracleAsyncConnectionPool":
289
305
  """Provide async pool instance.
290
306
 
291
307
  Returns:
@@ -298,8 +314,7 @@ class OracleAsyncConfig(AsyncDatabaseConfig[OracleAsyncConnection, "AsyncConnect
298
314
  def get_signature_namespace(self) -> "dict[str, type[Any]]":
299
315
  """Get the signature namespace for OracleDB async types.
300
316
 
301
- This provides all OracleDB async-specific types that Litestar needs to recognize
302
- to avoid serialization attempts.
317
+ Provides OracleDB async-specific types for Litestar framework recognition.
303
318
 
304
319
  Returns:
305
320
  Dictionary mapping type names to types.
@@ -310,6 +325,8 @@ class OracleAsyncConfig(AsyncDatabaseConfig[OracleAsyncConnection, "AsyncConnect
310
325
  {
311
326
  "OracleSyncConnection": OracleSyncConnection,
312
327
  "OracleAsyncConnection": OracleAsyncConnection,
328
+ "OracleSyncConnectionPool": OracleSyncConnectionPool,
329
+ "OracleAsyncConnectionPool": OracleAsyncConnectionPool,
313
330
  "OracleSyncCursor": OracleSyncCursor,
314
331
  "OracleAsyncCursor": OracleAsyncCursor,
315
332
  }