sqlspec 0.19.0__py3-none-any.whl → 0.21.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sqlspec might be problematic. Click here for more details.
- sqlspec/adapters/adbc/driver.py +192 -28
- sqlspec/adapters/asyncmy/driver.py +72 -15
- sqlspec/adapters/asyncpg/config.py +23 -3
- sqlspec/adapters/asyncpg/driver.py +30 -14
- sqlspec/adapters/bigquery/driver.py +79 -9
- sqlspec/adapters/duckdb/driver.py +39 -56
- sqlspec/adapters/oracledb/driver.py +99 -52
- sqlspec/adapters/psqlpy/driver.py +89 -31
- sqlspec/adapters/psycopg/driver.py +11 -23
- sqlspec/adapters/sqlite/driver.py +77 -8
- sqlspec/base.py +11 -11
- sqlspec/builder/__init__.py +1 -1
- sqlspec/builder/_base.py +4 -5
- sqlspec/builder/_column.py +3 -3
- sqlspec/builder/_ddl.py +5 -1
- sqlspec/builder/_delete.py +5 -6
- sqlspec/builder/_insert.py +6 -7
- sqlspec/builder/_merge.py +5 -5
- sqlspec/builder/_parsing_utils.py +3 -3
- sqlspec/builder/_select.py +6 -5
- sqlspec/builder/_update.py +4 -5
- sqlspec/builder/mixins/_cte_and_set_ops.py +5 -1
- sqlspec/builder/mixins/_delete_operations.py +5 -1
- sqlspec/builder/mixins/_insert_operations.py +5 -1
- sqlspec/builder/mixins/_join_operations.py +5 -0
- sqlspec/builder/mixins/_merge_operations.py +5 -1
- sqlspec/builder/mixins/_order_limit_operations.py +5 -1
- sqlspec/builder/mixins/_pivot_operations.py +4 -1
- sqlspec/builder/mixins/_select_operations.py +5 -1
- sqlspec/builder/mixins/_update_operations.py +5 -1
- sqlspec/builder/mixins/_where_clause.py +5 -1
- sqlspec/config.py +15 -15
- sqlspec/core/compiler.py +11 -3
- sqlspec/core/filters.py +30 -9
- sqlspec/core/parameters.py +67 -67
- sqlspec/core/result.py +62 -31
- sqlspec/core/splitter.py +160 -34
- sqlspec/core/statement.py +95 -14
- sqlspec/driver/_common.py +12 -3
- sqlspec/driver/mixins/_result_tools.py +21 -4
- sqlspec/driver/mixins/_sql_translator.py +45 -7
- sqlspec/extensions/aiosql/adapter.py +1 -1
- sqlspec/extensions/litestar/_utils.py +1 -1
- sqlspec/extensions/litestar/config.py +186 -2
- sqlspec/extensions/litestar/handlers.py +21 -0
- sqlspec/extensions/litestar/plugin.py +237 -3
- sqlspec/loader.py +12 -12
- sqlspec/migrations/loaders.py +5 -2
- sqlspec/migrations/utils.py +2 -2
- sqlspec/storage/backends/obstore.py +1 -3
- sqlspec/storage/registry.py +1 -1
- sqlspec/utils/__init__.py +7 -0
- sqlspec/utils/deprecation.py +6 -0
- sqlspec/utils/fixtures.py +239 -30
- sqlspec/utils/module_loader.py +5 -1
- sqlspec/utils/serializers.py +6 -0
- sqlspec/utils/singleton.py +6 -0
- sqlspec/utils/sync_tools.py +10 -1
- {sqlspec-0.19.0.dist-info → sqlspec-0.21.0.dist-info}/METADATA +230 -44
- {sqlspec-0.19.0.dist-info → sqlspec-0.21.0.dist-info}/RECORD +64 -64
- {sqlspec-0.19.0.dist-info → sqlspec-0.21.0.dist-info}/WHEEL +0 -0
- {sqlspec-0.19.0.dist-info → sqlspec-0.21.0.dist-info}/entry_points.txt +0 -0
- {sqlspec-0.19.0.dist-info → sqlspec-0.21.0.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.19.0.dist-info → sqlspec-0.21.0.dist-info}/licenses/NOTICE +0 -0
|
@@ -50,7 +50,11 @@ _BQ_TYPE_MAP: dict[type, tuple[str, Optional[str]]] = {
|
|
|
50
50
|
def _get_bq_param_type(value: Any) -> tuple[Optional[str], Optional[str]]:
|
|
51
51
|
"""Determine BigQuery parameter type from Python value.
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
Args:
|
|
54
|
+
value: Python value to determine BigQuery type for
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Tuple of (parameter_type, array_element_type)
|
|
54
58
|
"""
|
|
55
59
|
if value is None:
|
|
56
60
|
return ("STRING", None)
|
|
@@ -88,7 +92,11 @@ _BQ_PARAM_CREATOR_MAP: dict[str, Any] = {
|
|
|
88
92
|
def _create_bq_parameters(parameters: Any) -> "list[Union[ArrayQueryParameter, ScalarQueryParameter]]":
|
|
89
93
|
"""Create BigQuery QueryParameter objects from parameters.
|
|
90
94
|
|
|
91
|
-
|
|
95
|
+
Args:
|
|
96
|
+
parameters: Dict of named parameters or list of positional parameters
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
List of BigQuery QueryParameter objects
|
|
92
100
|
"""
|
|
93
101
|
if not parameters:
|
|
94
102
|
return []
|
|
@@ -170,7 +178,16 @@ class BigQueryCursor:
|
|
|
170
178
|
return self.connection
|
|
171
179
|
|
|
172
180
|
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
173
|
-
|
|
181
|
+
"""Clean up cursor resources including active QueryJobs."""
|
|
182
|
+
if self.job is not None:
|
|
183
|
+
try:
|
|
184
|
+
# Cancel the job if it's still running to free up resources
|
|
185
|
+
if self.job.state in {"PENDING", "RUNNING"}:
|
|
186
|
+
self.job.cancel()
|
|
187
|
+
# Clear the job reference
|
|
188
|
+
self.job = None
|
|
189
|
+
except Exception:
|
|
190
|
+
logger.exception("Failed to cancel BigQuery job during cursor cleanup")
|
|
174
191
|
|
|
175
192
|
|
|
176
193
|
class BigQueryExceptionHandler:
|
|
@@ -258,7 +275,12 @@ class BigQueryDriver(SyncDriverAdapterBase):
|
|
|
258
275
|
return BigQueryExceptionHandler()
|
|
259
276
|
|
|
260
277
|
def _copy_job_config_attrs(self, source_config: QueryJobConfig, target_config: QueryJobConfig) -> None:
|
|
261
|
-
"""Copy non-private attributes from source config to target config.
|
|
278
|
+
"""Copy non-private attributes from source config to target config.
|
|
279
|
+
|
|
280
|
+
Args:
|
|
281
|
+
source_config: Configuration to copy attributes from
|
|
282
|
+
target_config: Configuration to copy attributes to
|
|
283
|
+
"""
|
|
262
284
|
for attr in dir(source_config):
|
|
263
285
|
if attr.startswith("_"):
|
|
264
286
|
continue
|
|
@@ -276,7 +298,17 @@ class BigQueryDriver(SyncDriverAdapterBase):
|
|
|
276
298
|
connection: Optional[BigQueryConnection] = None,
|
|
277
299
|
job_config: Optional[QueryJobConfig] = None,
|
|
278
300
|
) -> QueryJob:
|
|
279
|
-
"""Execute a BigQuery job with configuration support.
|
|
301
|
+
"""Execute a BigQuery job with configuration support.
|
|
302
|
+
|
|
303
|
+
Args:
|
|
304
|
+
sql_str: SQL string to execute
|
|
305
|
+
parameters: Query parameters
|
|
306
|
+
connection: Optional BigQuery connection override
|
|
307
|
+
job_config: Optional job configuration
|
|
308
|
+
|
|
309
|
+
Returns:
|
|
310
|
+
QueryJob object representing the executed job
|
|
311
|
+
"""
|
|
280
312
|
conn = connection or self.connection
|
|
281
313
|
|
|
282
314
|
final_job_config = QueryJobConfig()
|
|
@@ -294,7 +326,14 @@ class BigQueryDriver(SyncDriverAdapterBase):
|
|
|
294
326
|
|
|
295
327
|
@staticmethod
|
|
296
328
|
def _rows_to_results(rows_iterator: Any) -> list[dict[str, Any]]:
|
|
297
|
-
"""Convert BigQuery rows to dictionary format.
|
|
329
|
+
"""Convert BigQuery rows to dictionary format.
|
|
330
|
+
|
|
331
|
+
Args:
|
|
332
|
+
rows_iterator: BigQuery rows iterator
|
|
333
|
+
|
|
334
|
+
Returns:
|
|
335
|
+
List of dictionaries representing the rows
|
|
336
|
+
"""
|
|
298
337
|
return [dict(row) for row in rows_iterator]
|
|
299
338
|
|
|
300
339
|
def _try_special_handling(self, cursor: "Any", statement: "SQL") -> "Optional[SQLResult]":
|
|
@@ -316,7 +355,12 @@ class BigQueryDriver(SyncDriverAdapterBase):
|
|
|
316
355
|
def _transform_ast_with_literals(self, sql: str, parameters: Any) -> str:
|
|
317
356
|
"""Transform SQL AST by replacing placeholders with literal values.
|
|
318
357
|
|
|
319
|
-
|
|
358
|
+
Args:
|
|
359
|
+
sql: SQL string to transform
|
|
360
|
+
parameters: Parameters to embed as literals
|
|
361
|
+
|
|
362
|
+
Returns:
|
|
363
|
+
Transformed SQL string with literals embedded
|
|
320
364
|
"""
|
|
321
365
|
if not parameters:
|
|
322
366
|
return sql
|
|
@@ -367,7 +411,14 @@ class BigQueryDriver(SyncDriverAdapterBase):
|
|
|
367
411
|
return transformed_ast.sql(dialect="bigquery")
|
|
368
412
|
|
|
369
413
|
def _create_literal_node(self, value: Any) -> "exp.Expression":
|
|
370
|
-
"""Create a SQLGlot literal expression from a Python value.
|
|
414
|
+
"""Create a SQLGlot literal expression from a Python value.
|
|
415
|
+
|
|
416
|
+
Args:
|
|
417
|
+
value: Python value to convert to SQLGlot literal
|
|
418
|
+
|
|
419
|
+
Returns:
|
|
420
|
+
SQLGlot expression representing the literal value
|
|
421
|
+
"""
|
|
371
422
|
if value is None:
|
|
372
423
|
return exp.Null()
|
|
373
424
|
if isinstance(value, bool):
|
|
@@ -389,6 +440,13 @@ class BigQueryDriver(SyncDriverAdapterBase):
|
|
|
389
440
|
"""Execute SQL script with statement splitting and parameter handling.
|
|
390
441
|
|
|
391
442
|
Parameters are embedded as static values for script execution compatibility.
|
|
443
|
+
|
|
444
|
+
Args:
|
|
445
|
+
cursor: BigQuery cursor object
|
|
446
|
+
statement: SQL statement to execute
|
|
447
|
+
|
|
448
|
+
Returns:
|
|
449
|
+
ExecutionResult with script execution details
|
|
392
450
|
"""
|
|
393
451
|
sql, prepared_parameters = self._get_compiled_sql(statement, self.statement_config)
|
|
394
452
|
statements = self.split_script_statements(sql, statement.statement_config, strip_trailing_semicolon=True)
|
|
@@ -414,6 +472,13 @@ class BigQueryDriver(SyncDriverAdapterBase):
|
|
|
414
472
|
BigQuery doesn't support traditional execute_many with parameter batching.
|
|
415
473
|
Instead, we generate a script with multiple INSERT statements using
|
|
416
474
|
AST transformation to embed literals safely.
|
|
475
|
+
|
|
476
|
+
Args:
|
|
477
|
+
cursor: BigQuery cursor object
|
|
478
|
+
statement: SQL statement to execute with multiple parameter sets
|
|
479
|
+
|
|
480
|
+
Returns:
|
|
481
|
+
ExecutionResult with batch execution details
|
|
417
482
|
"""
|
|
418
483
|
|
|
419
484
|
parameters_list = statement.parameters
|
|
@@ -441,7 +506,12 @@ class BigQueryDriver(SyncDriverAdapterBase):
|
|
|
441
506
|
def _execute_statement(self, cursor: Any, statement: "SQL") -> ExecutionResult:
|
|
442
507
|
"""Execute single SQL statement with BigQuery data handling.
|
|
443
508
|
|
|
444
|
-
|
|
509
|
+
Args:
|
|
510
|
+
cursor: BigQuery cursor object
|
|
511
|
+
statement: SQL statement to execute
|
|
512
|
+
|
|
513
|
+
Returns:
|
|
514
|
+
ExecutionResult with query results and metadata
|
|
445
515
|
"""
|
|
446
516
|
sql, parameters = self._get_compiled_sql(statement, self.statement_config)
|
|
447
517
|
cursor.job = self._run_query_job(sql, parameters, connection=cursor)
|
|
@@ -1,17 +1,4 @@
|
|
|
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
|
|
13
|
-
- Multi-parameter style support
|
|
14
|
-
"""
|
|
1
|
+
"""DuckDB driver implementation."""
|
|
15
2
|
|
|
16
3
|
from typing import TYPE_CHECKING, Any, Final, Optional
|
|
17
4
|
|
|
@@ -80,7 +67,11 @@ class DuckDBCursor:
|
|
|
80
67
|
|
|
81
68
|
|
|
82
69
|
class DuckDBExceptionHandler:
|
|
83
|
-
"""
|
|
70
|
+
"""Context manager for handling DuckDB database exceptions.
|
|
71
|
+
|
|
72
|
+
Catches DuckDB-specific exceptions and converts them to appropriate
|
|
73
|
+
SQLSpec exception types for consistent error handling.
|
|
74
|
+
"""
|
|
84
75
|
|
|
85
76
|
__slots__ = ()
|
|
86
77
|
|
|
@@ -126,33 +117,14 @@ class DuckDBExceptionHandler:
|
|
|
126
117
|
|
|
127
118
|
|
|
128
119
|
class DuckDBDriver(SyncDriverAdapterBase):
|
|
129
|
-
"""DuckDB driver
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
- Parameter processing with type coercion
|
|
138
|
-
- DuckDB resource management
|
|
139
|
-
|
|
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
|
|
145
|
-
|
|
146
|
-
DuckDB Support:
|
|
147
|
-
- Multi-parameter style support (QMARK, NUMERIC, NAMED_DOLLAR)
|
|
148
|
-
- Script execution with statement splitting
|
|
149
|
-
- Batch operations with row counting
|
|
150
|
-
- DuckDB-specific exception handling
|
|
151
|
-
|
|
152
|
-
Compatibility:
|
|
153
|
-
- Backward compatibility with existing DuckDB driver interface
|
|
154
|
-
- StatementConfig API compatibility
|
|
155
|
-
- Transaction management patterns
|
|
120
|
+
"""Synchronous DuckDB database driver.
|
|
121
|
+
|
|
122
|
+
Provides SQL statement execution, transaction management, and result handling
|
|
123
|
+
for DuckDB databases. Supports multiple parameter styles including QMARK,
|
|
124
|
+
NUMERIC, and NAMED_DOLLAR formats.
|
|
125
|
+
|
|
126
|
+
The driver handles script execution, batch operations, and integrates with
|
|
127
|
+
the sqlspec.core modules for statement processing and caching.
|
|
156
128
|
"""
|
|
157
129
|
|
|
158
130
|
__slots__ = ()
|
|
@@ -177,34 +149,45 @@ class DuckDBDriver(SyncDriverAdapterBase):
|
|
|
177
149
|
super().__init__(connection=connection, statement_config=statement_config, driver_features=driver_features)
|
|
178
150
|
|
|
179
151
|
def with_cursor(self, connection: "DuckDBConnection") -> "DuckDBCursor":
|
|
180
|
-
"""Create context manager for DuckDB cursor.
|
|
152
|
+
"""Create context manager for DuckDB cursor.
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
connection: DuckDB connection instance
|
|
156
|
+
|
|
157
|
+
Returns:
|
|
158
|
+
DuckDBCursor context manager instance
|
|
159
|
+
"""
|
|
181
160
|
return DuckDBCursor(connection)
|
|
182
161
|
|
|
183
162
|
def handle_database_exceptions(self) -> "AbstractContextManager[None]":
|
|
184
|
-
"""Handle database-specific exceptions and wrap them appropriately.
|
|
163
|
+
"""Handle database-specific exceptions and wrap them appropriately.
|
|
164
|
+
|
|
165
|
+
Returns:
|
|
166
|
+
Context manager that catches and converts DuckDB exceptions
|
|
167
|
+
"""
|
|
185
168
|
return DuckDBExceptionHandler()
|
|
186
169
|
|
|
187
170
|
def _try_special_handling(self, cursor: Any, statement: SQL) -> "Optional[SQLResult]":
|
|
188
171
|
"""Handle DuckDB-specific special operations.
|
|
189
172
|
|
|
190
|
-
DuckDB
|
|
191
|
-
|
|
173
|
+
DuckDB does not require special operation handling, so this method
|
|
174
|
+
returns None to indicate standard execution should proceed.
|
|
192
175
|
|
|
193
176
|
Args:
|
|
194
177
|
cursor: DuckDB cursor object
|
|
195
178
|
statement: SQL statement to analyze
|
|
196
179
|
|
|
197
180
|
Returns:
|
|
198
|
-
None
|
|
181
|
+
None to indicate no special handling required
|
|
199
182
|
"""
|
|
200
183
|
_ = (cursor, statement)
|
|
201
184
|
return None
|
|
202
185
|
|
|
203
186
|
def _is_modifying_operation(self, statement: SQL) -> bool:
|
|
204
|
-
"""Check if the SQL statement
|
|
187
|
+
"""Check if the SQL statement modifies data.
|
|
205
188
|
|
|
206
|
-
|
|
207
|
-
to
|
|
189
|
+
Determines if a statement is an INSERT, UPDATE, or DELETE operation
|
|
190
|
+
using AST analysis when available, falling back to text parsing.
|
|
208
191
|
|
|
209
192
|
Args:
|
|
210
193
|
statement: SQL statement to analyze
|
|
@@ -223,8 +206,8 @@ class DuckDBDriver(SyncDriverAdapterBase):
|
|
|
223
206
|
def _execute_script(self, cursor: Any, statement: SQL) -> "ExecutionResult":
|
|
224
207
|
"""Execute SQL script with statement splitting and parameter handling.
|
|
225
208
|
|
|
226
|
-
|
|
227
|
-
|
|
209
|
+
Parses multi-statement scripts and executes each statement sequentially
|
|
210
|
+
with the provided parameters.
|
|
228
211
|
|
|
229
212
|
Args:
|
|
230
213
|
cursor: DuckDB cursor object
|
|
@@ -250,8 +233,8 @@ class DuckDBDriver(SyncDriverAdapterBase):
|
|
|
250
233
|
def _execute_many(self, cursor: Any, statement: SQL) -> "ExecutionResult":
|
|
251
234
|
"""Execute SQL with multiple parameter sets using batch processing.
|
|
252
235
|
|
|
253
|
-
Uses DuckDB's executemany for batch operations
|
|
254
|
-
row
|
|
236
|
+
Uses DuckDB's executemany method for batch operations and calculates
|
|
237
|
+
row counts for both data modification and query operations.
|
|
255
238
|
|
|
256
239
|
Args:
|
|
257
240
|
cursor: DuckDB cursor object
|
|
@@ -281,8 +264,8 @@ class DuckDBDriver(SyncDriverAdapterBase):
|
|
|
281
264
|
def _execute_statement(self, cursor: Any, statement: SQL) -> "ExecutionResult":
|
|
282
265
|
"""Execute single SQL statement with data handling.
|
|
283
266
|
|
|
284
|
-
|
|
285
|
-
Handles both
|
|
267
|
+
Executes a SQL statement with parameter binding and processes the results.
|
|
268
|
+
Handles both data-returning queries and data modification operations.
|
|
286
269
|
|
|
287
270
|
Args:
|
|
288
271
|
cursor: DuckDB cursor object
|
|
@@ -1,26 +1,4 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
3
|
-
This driver implements the complete CORE_ROUND_3 architecture for Oracle Database connections:
|
|
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 Oracle functionality
|
|
8
|
-
|
|
9
|
-
Architecture Features:
|
|
10
|
-
- Direct integration with sqlspec.core modules
|
|
11
|
-
- Enhanced Oracle parameter processing with QMARK/COLON conversion
|
|
12
|
-
- Thread-safe unified caching system
|
|
13
|
-
- MyPyC-optimized performance patterns
|
|
14
|
-
- Zero-copy data access where possible
|
|
15
|
-
- Both sync and async context management
|
|
16
|
-
|
|
17
|
-
Oracle Features:
|
|
18
|
-
- Parameter style conversion (QMARK to NAMED_COLON/POSITIONAL_COLON)
|
|
19
|
-
- Oracle-specific type coercion and data handling
|
|
20
|
-
- Enhanced error categorization for Oracle database errors
|
|
21
|
-
- Transaction management with automatic commit/rollback
|
|
22
|
-
- Support for both sync and async execution modes
|
|
23
|
-
"""
|
|
1
|
+
"""Oracle Driver"""
|
|
24
2
|
|
|
25
3
|
import logging
|
|
26
4
|
from typing import TYPE_CHECKING, Any, Optional
|
|
@@ -53,20 +31,18 @@ __all__ = (
|
|
|
53
31
|
)
|
|
54
32
|
|
|
55
33
|
|
|
56
|
-
# Enhanced Oracle statement configuration using core modules with performance optimizations
|
|
57
34
|
oracledb_statement_config = StatementConfig(
|
|
58
35
|
dialect="oracle",
|
|
59
36
|
parameter_config=ParameterStyleConfig(
|
|
60
|
-
default_parameter_style=ParameterStyle.POSITIONAL_COLON,
|
|
37
|
+
default_parameter_style=ParameterStyle.POSITIONAL_COLON,
|
|
61
38
|
supported_parameter_styles={ParameterStyle.NAMED_COLON, ParameterStyle.POSITIONAL_COLON, ParameterStyle.QMARK},
|
|
62
|
-
default_execution_parameter_style=ParameterStyle.POSITIONAL_COLON,
|
|
39
|
+
default_execution_parameter_style=ParameterStyle.POSITIONAL_COLON,
|
|
63
40
|
supported_execution_parameter_styles={ParameterStyle.NAMED_COLON, ParameterStyle.POSITIONAL_COLON},
|
|
64
41
|
type_coercion_map={},
|
|
65
42
|
has_native_list_expansion=False,
|
|
66
43
|
needs_static_script_compilation=True,
|
|
67
44
|
preserve_parameter_format=True,
|
|
68
45
|
),
|
|
69
|
-
# Core processing features enabled for performance
|
|
70
46
|
enable_parsing=True,
|
|
71
47
|
enable_validation=True,
|
|
72
48
|
enable_caching=True,
|
|
@@ -75,7 +51,7 @@ oracledb_statement_config = StatementConfig(
|
|
|
75
51
|
|
|
76
52
|
|
|
77
53
|
class OracleSyncCursor:
|
|
78
|
-
"""Sync context manager for Oracle cursor management
|
|
54
|
+
"""Sync context manager for Oracle cursor management."""
|
|
79
55
|
|
|
80
56
|
__slots__ = ("connection", "cursor")
|
|
81
57
|
|
|
@@ -94,7 +70,7 @@ class OracleSyncCursor:
|
|
|
94
70
|
|
|
95
71
|
|
|
96
72
|
class OracleAsyncCursor:
|
|
97
|
-
"""Async context manager for Oracle cursor management
|
|
73
|
+
"""Async context manager for Oracle cursor management."""
|
|
98
74
|
|
|
99
75
|
__slots__ = ("connection", "cursor")
|
|
100
76
|
|
|
@@ -113,7 +89,7 @@ class OracleAsyncCursor:
|
|
|
113
89
|
|
|
114
90
|
|
|
115
91
|
class OracleSyncExceptionHandler:
|
|
116
|
-
"""
|
|
92
|
+
"""Context manager for handling Oracle database exceptions in synchronous operations."""
|
|
117
93
|
|
|
118
94
|
__slots__ = ()
|
|
119
95
|
|
|
@@ -160,7 +136,7 @@ class OracleSyncExceptionHandler:
|
|
|
160
136
|
|
|
161
137
|
|
|
162
138
|
class OracleAsyncExceptionHandler:
|
|
163
|
-
"""
|
|
139
|
+
"""Context manager for handling Oracle database exceptions in asynchronous operations."""
|
|
164
140
|
|
|
165
141
|
__slots__ = ()
|
|
166
142
|
|
|
@@ -222,21 +198,26 @@ class OracleSyncDriver(SyncDriverAdapterBase):
|
|
|
222
198
|
statement_config: "Optional[StatementConfig]" = None,
|
|
223
199
|
driver_features: "Optional[dict[str, Any]]" = None,
|
|
224
200
|
) -> None:
|
|
225
|
-
# Configure with default settings
|
|
226
201
|
if statement_config is None:
|
|
227
202
|
cache_config = get_cache_config()
|
|
228
|
-
|
|
203
|
+
statement_config = oracledb_statement_config.replace(
|
|
229
204
|
enable_caching=cache_config.compiled_cache_enabled,
|
|
230
205
|
enable_parsing=True,
|
|
231
206
|
enable_validation=True,
|
|
232
207
|
dialect="oracle",
|
|
233
208
|
)
|
|
234
|
-
statement_config = enhanced_config
|
|
235
209
|
|
|
236
210
|
super().__init__(connection=connection, statement_config=statement_config, driver_features=driver_features)
|
|
237
211
|
|
|
238
212
|
def with_cursor(self, connection: OracleSyncConnection) -> OracleSyncCursor:
|
|
239
|
-
"""Create
|
|
213
|
+
"""Create context manager for Oracle cursor.
|
|
214
|
+
|
|
215
|
+
Args:
|
|
216
|
+
connection: Oracle database connection
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
Context manager for cursor operations
|
|
220
|
+
"""
|
|
240
221
|
return OracleSyncCursor(connection)
|
|
241
222
|
|
|
242
223
|
def handle_database_exceptions(self) -> "AbstractContextManager[None]":
|
|
@@ -260,10 +241,16 @@ class OracleSyncDriver(SyncDriverAdapterBase):
|
|
|
260
241
|
return None
|
|
261
242
|
|
|
262
243
|
def _execute_script(self, cursor: Any, statement: "SQL") -> "ExecutionResult":
|
|
263
|
-
"""Execute SQL script
|
|
244
|
+
"""Execute SQL script with statement splitting and parameter handling.
|
|
264
245
|
|
|
265
|
-
Uses core module optimization for statement parsing and parameter processing.
|
|
266
246
|
Parameters are embedded as static values for script execution compatibility.
|
|
247
|
+
|
|
248
|
+
Args:
|
|
249
|
+
cursor: Oracle cursor object
|
|
250
|
+
statement: SQL script statement to execute
|
|
251
|
+
|
|
252
|
+
Returns:
|
|
253
|
+
Execution result containing statement count and success information
|
|
267
254
|
"""
|
|
268
255
|
sql, prepared_parameters = self._get_compiled_sql(statement, self.statement_config)
|
|
269
256
|
statements = self.split_script_statements(sql, statement.statement_config, strip_trailing_semicolon=True)
|
|
@@ -280,9 +267,17 @@ class OracleSyncDriver(SyncDriverAdapterBase):
|
|
|
280
267
|
)
|
|
281
268
|
|
|
282
269
|
def _execute_many(self, cursor: Any, statement: "SQL") -> "ExecutionResult":
|
|
283
|
-
"""Execute SQL with multiple parameter sets using
|
|
270
|
+
"""Execute SQL with multiple parameter sets using Oracle batch processing.
|
|
271
|
+
|
|
272
|
+
Args:
|
|
273
|
+
cursor: Oracle cursor object
|
|
274
|
+
statement: SQL statement with multiple parameter sets
|
|
275
|
+
|
|
276
|
+
Returns:
|
|
277
|
+
Execution result with affected row count
|
|
284
278
|
|
|
285
|
-
|
|
279
|
+
Raises:
|
|
280
|
+
ValueError: If no parameters are provided
|
|
286
281
|
"""
|
|
287
282
|
sql, prepared_parameters = self._get_compiled_sql(statement, self.statement_config)
|
|
288
283
|
|
|
@@ -299,9 +294,14 @@ class OracleSyncDriver(SyncDriverAdapterBase):
|
|
|
299
294
|
return self.create_execution_result(cursor, rowcount_override=affected_rows, is_many_result=True)
|
|
300
295
|
|
|
301
296
|
def _execute_statement(self, cursor: Any, statement: "SQL") -> "ExecutionResult":
|
|
302
|
-
"""Execute single SQL statement with
|
|
297
|
+
"""Execute single SQL statement with Oracle data handling.
|
|
303
298
|
|
|
304
|
-
|
|
299
|
+
Args:
|
|
300
|
+
cursor: Oracle cursor object
|
|
301
|
+
statement: SQL statement to execute
|
|
302
|
+
|
|
303
|
+
Returns:
|
|
304
|
+
Execution result containing data for SELECT statements or row count for others
|
|
305
305
|
"""
|
|
306
306
|
sql, prepared_parameters = self._get_compiled_sql(statement, self.statement_config)
|
|
307
307
|
cursor.execute(sql, prepared_parameters or {})
|
|
@@ -324,14 +324,18 @@ class OracleSyncDriver(SyncDriverAdapterBase):
|
|
|
324
324
|
|
|
325
325
|
# Oracle transaction management
|
|
326
326
|
def begin(self) -> None:
|
|
327
|
-
"""Begin a database transaction
|
|
327
|
+
"""Begin a database transaction.
|
|
328
328
|
|
|
329
329
|
Oracle handles transactions automatically, so this is a no-op.
|
|
330
330
|
"""
|
|
331
331
|
# Oracle handles transactions implicitly
|
|
332
332
|
|
|
333
333
|
def rollback(self) -> None:
|
|
334
|
-
"""Rollback the current transaction
|
|
334
|
+
"""Rollback the current transaction.
|
|
335
|
+
|
|
336
|
+
Raises:
|
|
337
|
+
SQLSpecError: If rollback fails
|
|
338
|
+
"""
|
|
335
339
|
try:
|
|
336
340
|
self.connection.rollback()
|
|
337
341
|
except oracledb.Error as e:
|
|
@@ -339,7 +343,11 @@ class OracleSyncDriver(SyncDriverAdapterBase):
|
|
|
339
343
|
raise SQLSpecError(msg) from e
|
|
340
344
|
|
|
341
345
|
def commit(self) -> None:
|
|
342
|
-
"""Commit the current transaction
|
|
346
|
+
"""Commit the current transaction.
|
|
347
|
+
|
|
348
|
+
Raises:
|
|
349
|
+
SQLSpecError: If commit fails
|
|
350
|
+
"""
|
|
343
351
|
try:
|
|
344
352
|
self.connection.commit()
|
|
345
353
|
except oracledb.Error as e:
|
|
@@ -363,21 +371,26 @@ class OracleAsyncDriver(AsyncDriverAdapterBase):
|
|
|
363
371
|
statement_config: "Optional[StatementConfig]" = None,
|
|
364
372
|
driver_features: "Optional[dict[str, Any]]" = None,
|
|
365
373
|
) -> None:
|
|
366
|
-
# Configure with default settings
|
|
367
374
|
if statement_config is None:
|
|
368
375
|
cache_config = get_cache_config()
|
|
369
|
-
|
|
376
|
+
statement_config = oracledb_statement_config.replace(
|
|
370
377
|
enable_caching=cache_config.compiled_cache_enabled,
|
|
371
378
|
enable_parsing=True,
|
|
372
379
|
enable_validation=True,
|
|
373
380
|
dialect="oracle",
|
|
374
381
|
)
|
|
375
|
-
statement_config = enhanced_config
|
|
376
382
|
|
|
377
383
|
super().__init__(connection=connection, statement_config=statement_config, driver_features=driver_features)
|
|
378
384
|
|
|
379
385
|
def with_cursor(self, connection: OracleAsyncConnection) -> OracleAsyncCursor:
|
|
380
|
-
"""Create
|
|
386
|
+
"""Create context manager for Oracle cursor.
|
|
387
|
+
|
|
388
|
+
Args:
|
|
389
|
+
connection: Oracle database connection
|
|
390
|
+
|
|
391
|
+
Returns:
|
|
392
|
+
Context manager for cursor operations
|
|
393
|
+
"""
|
|
381
394
|
return OracleAsyncCursor(connection)
|
|
382
395
|
|
|
383
396
|
def handle_database_exceptions(self) -> "AbstractAsyncContextManager[None]":
|
|
@@ -404,6 +417,13 @@ class OracleAsyncDriver(AsyncDriverAdapterBase):
|
|
|
404
417
|
"""Execute SQL script with statement splitting and parameter handling.
|
|
405
418
|
|
|
406
419
|
Parameters are embedded as static values for script execution compatibility.
|
|
420
|
+
|
|
421
|
+
Args:
|
|
422
|
+
cursor: Oracle cursor object
|
|
423
|
+
statement: SQL script statement to execute
|
|
424
|
+
|
|
425
|
+
Returns:
|
|
426
|
+
Execution result containing statement count and success information
|
|
407
427
|
"""
|
|
408
428
|
sql, prepared_parameters = self._get_compiled_sql(statement, self.statement_config)
|
|
409
429
|
statements = self.split_script_statements(sql, statement.statement_config, strip_trailing_semicolon=True)
|
|
@@ -420,7 +440,18 @@ class OracleAsyncDriver(AsyncDriverAdapterBase):
|
|
|
420
440
|
)
|
|
421
441
|
|
|
422
442
|
async def _execute_many(self, cursor: Any, statement: "SQL") -> "ExecutionResult":
|
|
423
|
-
"""Execute SQL with multiple parameter sets using Oracle batch processing.
|
|
443
|
+
"""Execute SQL with multiple parameter sets using Oracle batch processing.
|
|
444
|
+
|
|
445
|
+
Args:
|
|
446
|
+
cursor: Oracle cursor object
|
|
447
|
+
statement: SQL statement with multiple parameter sets
|
|
448
|
+
|
|
449
|
+
Returns:
|
|
450
|
+
Execution result with affected row count
|
|
451
|
+
|
|
452
|
+
Raises:
|
|
453
|
+
ValueError: If no parameters are provided
|
|
454
|
+
"""
|
|
424
455
|
sql, prepared_parameters = self._get_compiled_sql(statement, self.statement_config)
|
|
425
456
|
|
|
426
457
|
# Parameter validation for executemany
|
|
@@ -436,7 +467,15 @@ class OracleAsyncDriver(AsyncDriverAdapterBase):
|
|
|
436
467
|
return self.create_execution_result(cursor, rowcount_override=affected_rows, is_many_result=True)
|
|
437
468
|
|
|
438
469
|
async def _execute_statement(self, cursor: Any, statement: "SQL") -> "ExecutionResult":
|
|
439
|
-
"""Execute single SQL statement with Oracle data handling.
|
|
470
|
+
"""Execute single SQL statement with Oracle data handling.
|
|
471
|
+
|
|
472
|
+
Args:
|
|
473
|
+
cursor: Oracle cursor object
|
|
474
|
+
statement: SQL statement to execute
|
|
475
|
+
|
|
476
|
+
Returns:
|
|
477
|
+
Execution result containing data for SELECT statements or row count for others
|
|
478
|
+
"""
|
|
440
479
|
sql, prepared_parameters = self._get_compiled_sql(statement, self.statement_config)
|
|
441
480
|
await cursor.execute(sql, prepared_parameters or {})
|
|
442
481
|
|
|
@@ -465,7 +504,11 @@ class OracleAsyncDriver(AsyncDriverAdapterBase):
|
|
|
465
504
|
# Oracle handles transactions implicitly
|
|
466
505
|
|
|
467
506
|
async def rollback(self) -> None:
|
|
468
|
-
"""Rollback the current transaction.
|
|
507
|
+
"""Rollback the current transaction.
|
|
508
|
+
|
|
509
|
+
Raises:
|
|
510
|
+
SQLSpecError: If rollback fails
|
|
511
|
+
"""
|
|
469
512
|
try:
|
|
470
513
|
await self.connection.rollback()
|
|
471
514
|
except oracledb.Error as e:
|
|
@@ -473,7 +516,11 @@ class OracleAsyncDriver(AsyncDriverAdapterBase):
|
|
|
473
516
|
raise SQLSpecError(msg) from e
|
|
474
517
|
|
|
475
518
|
async def commit(self) -> None:
|
|
476
|
-
"""Commit the current transaction.
|
|
519
|
+
"""Commit the current transaction.
|
|
520
|
+
|
|
521
|
+
Raises:
|
|
522
|
+
SQLSpecError: If commit fails
|
|
523
|
+
"""
|
|
477
524
|
try:
|
|
478
525
|
await self.connection.commit()
|
|
479
526
|
except oracledb.Error as e:
|