sqlspec 0.19.0__py3-none-any.whl → 0.20.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/handlers.py +21 -0
- 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.20.0.dist-info}/METADATA +1 -1
- {sqlspec-0.19.0.dist-info → sqlspec-0.20.0.dist-info}/RECORD +62 -62
- {sqlspec-0.19.0.dist-info → sqlspec-0.20.0.dist-info}/WHEEL +0 -0
- {sqlspec-0.19.0.dist-info → sqlspec-0.20.0.dist-info}/entry_points.txt +0 -0
- {sqlspec-0.19.0.dist-info → sqlspec-0.20.0.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.19.0.dist-info → sqlspec-0.20.0.dist-info}/licenses/NOTICE +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"""Psqlpy driver implementation.
|
|
1
|
+
"""Psqlpy driver implementation for PostgreSQL connectivity.
|
|
2
2
|
|
|
3
|
-
Provides
|
|
4
|
-
|
|
3
|
+
Provides parameter style conversion, type coercion, error handling,
|
|
4
|
+
and transaction management.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import datetime
|
|
@@ -39,7 +39,7 @@ psqlpy_statement_config = StatementConfig(
|
|
|
39
39
|
default_execution_parameter_style=ParameterStyle.NUMERIC,
|
|
40
40
|
supported_execution_parameter_styles={ParameterStyle.NUMERIC},
|
|
41
41
|
type_coercion_map={tuple: list, decimal.Decimal: float},
|
|
42
|
-
has_native_list_expansion=
|
|
42
|
+
has_native_list_expansion=False,
|
|
43
43
|
needs_static_script_compilation=False,
|
|
44
44
|
allow_mixed_parameter_styles=False,
|
|
45
45
|
preserve_parameter_format=True,
|
|
@@ -72,8 +72,8 @@ SPECIAL_TYPE_REGEX: Final[re.Pattern[str]] = re.compile(
|
|
|
72
72
|
def _detect_postgresql_type(value: str) -> Optional[str]:
|
|
73
73
|
"""Detect PostgreSQL data type from string value.
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
Args:
|
|
76
|
+
value: String value to analyze
|
|
77
77
|
|
|
78
78
|
Returns:
|
|
79
79
|
Type name if detected, None otherwise.
|
|
@@ -101,7 +101,14 @@ def _detect_postgresql_type(value: str) -> Optional[str]:
|
|
|
101
101
|
|
|
102
102
|
|
|
103
103
|
def _convert_uuid(value: str) -> Any:
|
|
104
|
-
"""Convert UUID string to UUID object.
|
|
104
|
+
"""Convert UUID string to UUID object.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
value: UUID string to convert
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
UUID object or original value if conversion fails
|
|
111
|
+
"""
|
|
105
112
|
try:
|
|
106
113
|
clean_uuid = value.replace("-", "").lower()
|
|
107
114
|
uuid_length = 32
|
|
@@ -114,7 +121,14 @@ def _convert_uuid(value: str) -> Any:
|
|
|
114
121
|
|
|
115
122
|
|
|
116
123
|
def _convert_iso_datetime(value: str) -> Any:
|
|
117
|
-
"""Convert ISO datetime string to datetime object.
|
|
124
|
+
"""Convert ISO datetime string to datetime object.
|
|
125
|
+
|
|
126
|
+
Args:
|
|
127
|
+
value: ISO datetime string to convert
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
datetime object or original value if conversion fails
|
|
131
|
+
"""
|
|
118
132
|
try:
|
|
119
133
|
normalized = value.replace("Z", "+00:00")
|
|
120
134
|
return datetime.datetime.fromisoformat(normalized)
|
|
@@ -123,7 +137,14 @@ def _convert_iso_datetime(value: str) -> Any:
|
|
|
123
137
|
|
|
124
138
|
|
|
125
139
|
def _convert_iso_date(value: str) -> Any:
|
|
126
|
-
"""Convert ISO date string to date object.
|
|
140
|
+
"""Convert ISO date string to date object.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
value: ISO date string to convert
|
|
144
|
+
|
|
145
|
+
Returns:
|
|
146
|
+
date object or original value if conversion fails
|
|
147
|
+
"""
|
|
127
148
|
try:
|
|
128
149
|
return datetime.date.fromisoformat(value)
|
|
129
150
|
except ValueError:
|
|
@@ -131,7 +152,14 @@ def _convert_iso_date(value: str) -> Any:
|
|
|
131
152
|
|
|
132
153
|
|
|
133
154
|
def _validate_json(value: str) -> str:
|
|
134
|
-
"""Validate JSON string
|
|
155
|
+
"""Validate JSON string format.
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
value: JSON string to validate
|
|
159
|
+
|
|
160
|
+
Returns:
|
|
161
|
+
Original string value
|
|
162
|
+
"""
|
|
135
163
|
from sqlspec.utils.serializers import from_json
|
|
136
164
|
|
|
137
165
|
try:
|
|
@@ -142,7 +170,14 @@ def _validate_json(value: str) -> str:
|
|
|
142
170
|
|
|
143
171
|
|
|
144
172
|
def _passthrough(value: str) -> str:
|
|
145
|
-
"""Pass value through unchanged.
|
|
173
|
+
"""Pass value through unchanged.
|
|
174
|
+
|
|
175
|
+
Args:
|
|
176
|
+
value: String value to pass through
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
Original value unchanged
|
|
180
|
+
"""
|
|
146
181
|
return value
|
|
147
182
|
|
|
148
183
|
|
|
@@ -161,15 +196,13 @@ _PSQLPY_TYPE_CONVERTERS: dict[str, Any] = {
|
|
|
161
196
|
|
|
162
197
|
|
|
163
198
|
def _convert_psqlpy_parameters(value: Any) -> Any:
|
|
164
|
-
"""Convert parameters for
|
|
165
|
-
|
|
166
|
-
Performs type conversions based on detected PostgreSQL types.
|
|
199
|
+
"""Convert parameters for psqlpy compatibility.
|
|
167
200
|
|
|
168
201
|
Args:
|
|
169
202
|
value: Parameter value to convert
|
|
170
203
|
|
|
171
204
|
Returns:
|
|
172
|
-
Converted value suitable for psqlpy
|
|
205
|
+
Converted value suitable for psqlpy execution
|
|
173
206
|
"""
|
|
174
207
|
if isinstance(value, str):
|
|
175
208
|
detected_type = _detect_postgresql_type(value)
|
|
@@ -188,7 +221,7 @@ def _convert_psqlpy_parameters(value: Any) -> Any:
|
|
|
188
221
|
|
|
189
222
|
|
|
190
223
|
class PsqlpyCursor:
|
|
191
|
-
"""Context manager for
|
|
224
|
+
"""Context manager for psqlpy cursor management."""
|
|
192
225
|
|
|
193
226
|
__slots__ = ("_in_use", "connection")
|
|
194
227
|
|
|
@@ -197,22 +230,36 @@ class PsqlpyCursor:
|
|
|
197
230
|
self._in_use = False
|
|
198
231
|
|
|
199
232
|
async def __aenter__(self) -> "PsqlpyConnection":
|
|
200
|
-
"""Enter cursor context.
|
|
233
|
+
"""Enter cursor context.
|
|
234
|
+
|
|
235
|
+
Returns:
|
|
236
|
+
Psqlpy connection object
|
|
237
|
+
"""
|
|
201
238
|
self._in_use = True
|
|
202
239
|
return self.connection
|
|
203
240
|
|
|
204
241
|
async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
205
|
-
"""Exit cursor context.
|
|
242
|
+
"""Exit cursor context.
|
|
243
|
+
|
|
244
|
+
Args:
|
|
245
|
+
exc_type: Exception type
|
|
246
|
+
exc_val: Exception value
|
|
247
|
+
exc_tb: Exception traceback
|
|
248
|
+
"""
|
|
206
249
|
_ = (exc_type, exc_val, exc_tb)
|
|
207
250
|
self._in_use = False
|
|
208
251
|
|
|
209
252
|
def is_in_use(self) -> bool:
|
|
210
|
-
"""Check if cursor is currently in use.
|
|
253
|
+
"""Check if cursor is currently in use.
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
True if cursor is in use, False otherwise
|
|
257
|
+
"""
|
|
211
258
|
return self._in_use
|
|
212
259
|
|
|
213
260
|
|
|
214
261
|
class PsqlpyExceptionHandler:
|
|
215
|
-
"""
|
|
262
|
+
"""Async context manager for handling psqlpy database exceptions."""
|
|
216
263
|
|
|
217
264
|
__slots__ = ()
|
|
218
265
|
|
|
@@ -250,10 +297,10 @@ class PsqlpyExceptionHandler:
|
|
|
250
297
|
|
|
251
298
|
|
|
252
299
|
class PsqlpyDriver(AsyncDriverAdapterBase):
|
|
253
|
-
"""
|
|
300
|
+
"""PostgreSQL driver implementation using psqlpy.
|
|
254
301
|
|
|
255
|
-
Provides
|
|
256
|
-
|
|
302
|
+
Provides parameter style conversion, type coercion, error handling,
|
|
303
|
+
and transaction management.
|
|
257
304
|
"""
|
|
258
305
|
|
|
259
306
|
__slots__ = ()
|
|
@@ -277,11 +324,22 @@ class PsqlpyDriver(AsyncDriverAdapterBase):
|
|
|
277
324
|
super().__init__(connection=connection, statement_config=statement_config, driver_features=driver_features)
|
|
278
325
|
|
|
279
326
|
def with_cursor(self, connection: "PsqlpyConnection") -> "PsqlpyCursor":
|
|
280
|
-
"""Create context manager for psqlpy cursor.
|
|
327
|
+
"""Create context manager for psqlpy cursor.
|
|
328
|
+
|
|
329
|
+
Args:
|
|
330
|
+
connection: Psqlpy connection object
|
|
331
|
+
|
|
332
|
+
Returns:
|
|
333
|
+
PsqlpyCursor context manager
|
|
334
|
+
"""
|
|
281
335
|
return PsqlpyCursor(connection)
|
|
282
336
|
|
|
283
337
|
def handle_database_exceptions(self) -> "AbstractAsyncContextManager[None]":
|
|
284
|
-
"""Handle database-specific exceptions
|
|
338
|
+
"""Handle database-specific exceptions.
|
|
339
|
+
|
|
340
|
+
Returns:
|
|
341
|
+
Exception handler context manager
|
|
342
|
+
"""
|
|
285
343
|
return PsqlpyExceptionHandler()
|
|
286
344
|
|
|
287
345
|
async def _try_special_handling(self, cursor: "PsqlpyConnection", statement: SQL) -> "Optional[SQLResult]":
|
|
@@ -292,13 +350,13 @@ class PsqlpyDriver(AsyncDriverAdapterBase):
|
|
|
292
350
|
statement: SQL statement to analyze
|
|
293
351
|
|
|
294
352
|
Returns:
|
|
295
|
-
|
|
353
|
+
SQLResult if special handling applied, None otherwise
|
|
296
354
|
"""
|
|
297
355
|
_ = (cursor, statement)
|
|
298
356
|
return None
|
|
299
357
|
|
|
300
358
|
async def _execute_script(self, cursor: "PsqlpyConnection", statement: SQL) -> "ExecutionResult":
|
|
301
|
-
"""Execute SQL script with statement splitting
|
|
359
|
+
"""Execute SQL script with statement splitting.
|
|
302
360
|
|
|
303
361
|
Args:
|
|
304
362
|
cursor: Psqlpy connection object
|
|
@@ -329,7 +387,7 @@ class PsqlpyDriver(AsyncDriverAdapterBase):
|
|
|
329
387
|
)
|
|
330
388
|
|
|
331
389
|
async def _execute_many(self, cursor: "PsqlpyConnection", statement: SQL) -> "ExecutionResult":
|
|
332
|
-
"""Execute SQL with multiple parameter sets
|
|
390
|
+
"""Execute SQL with multiple parameter sets.
|
|
333
391
|
|
|
334
392
|
Args:
|
|
335
393
|
cursor: Psqlpy connection object
|
|
@@ -358,7 +416,7 @@ class PsqlpyDriver(AsyncDriverAdapterBase):
|
|
|
358
416
|
return self.create_execution_result(cursor, rowcount_override=rows_affected, is_many_result=True)
|
|
359
417
|
|
|
360
418
|
async def _execute_statement(self, cursor: "PsqlpyConnection", statement: SQL) -> "ExecutionResult":
|
|
361
|
-
"""Execute single SQL statement
|
|
419
|
+
"""Execute single SQL statement.
|
|
362
420
|
|
|
363
421
|
Args:
|
|
364
422
|
cursor: Psqlpy connection object
|
|
@@ -396,7 +454,7 @@ class PsqlpyDriver(AsyncDriverAdapterBase):
|
|
|
396
454
|
result: Psqlpy execution result object
|
|
397
455
|
|
|
398
456
|
Returns:
|
|
399
|
-
Number of rows affected,
|
|
457
|
+
Number of rows affected, -1 if unable to determine
|
|
400
458
|
"""
|
|
401
459
|
try:
|
|
402
460
|
if hasattr(result, "tag") and result.tag:
|
|
@@ -416,7 +474,7 @@ class PsqlpyDriver(AsyncDriverAdapterBase):
|
|
|
416
474
|
tag: PostgreSQL command tag string
|
|
417
475
|
|
|
418
476
|
Returns:
|
|
419
|
-
Number of rows affected,
|
|
477
|
+
Number of rows affected, -1 if unable to parse
|
|
420
478
|
"""
|
|
421
479
|
if not tag:
|
|
422
480
|
return -1
|
|
@@ -180,17 +180,11 @@ class PsycopgSyncExceptionHandler:
|
|
|
180
180
|
class PsycopgSyncDriver(SyncDriverAdapterBase):
|
|
181
181
|
"""PostgreSQL psycopg synchronous driver.
|
|
182
182
|
|
|
183
|
-
Provides synchronous database operations for PostgreSQL using psycopg3
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
PostgreSQL Features:
|
|
190
|
-
- Parameter styles ($1, %s, %(name)s)
|
|
191
|
-
- PostgreSQL arrays and JSON handling
|
|
192
|
-
- COPY operations for bulk data transfer
|
|
193
|
-
- PostgreSQL-specific error handling
|
|
183
|
+
Provides synchronous database operations for PostgreSQL using psycopg3.
|
|
184
|
+
Supports SQL statement execution with parameter binding, transaction
|
|
185
|
+
management, result processing with column metadata, parameter style
|
|
186
|
+
conversion, PostgreSQL arrays and JSON handling, COPY operations for
|
|
187
|
+
bulk data transfer, and PostgreSQL-specific error handling.
|
|
194
188
|
"""
|
|
195
189
|
|
|
196
190
|
__slots__ = ()
|
|
@@ -486,18 +480,12 @@ class PsycopgAsyncExceptionHandler:
|
|
|
486
480
|
class PsycopgAsyncDriver(AsyncDriverAdapterBase):
|
|
487
481
|
"""PostgreSQL psycopg asynchronous driver.
|
|
488
482
|
|
|
489
|
-
Provides asynchronous database operations for PostgreSQL using psycopg3
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
PostgreSQL Features:
|
|
496
|
-
- Parameter styles ($1, %s, %(name)s)
|
|
497
|
-
- PostgreSQL arrays and JSON handling
|
|
498
|
-
- COPY operations for bulk data transfer
|
|
499
|
-
- PostgreSQL-specific error handling
|
|
500
|
-
- Async pub/sub support (LISTEN/NOTIFY)
|
|
483
|
+
Provides asynchronous database operations for PostgreSQL using psycopg3.
|
|
484
|
+
Supports async SQL statement execution with parameter binding, async
|
|
485
|
+
transaction management, async result processing with column metadata,
|
|
486
|
+
parameter style conversion, PostgreSQL arrays and JSON handling, COPY
|
|
487
|
+
operations for bulk data transfer, PostgreSQL-specific error handling,
|
|
488
|
+
and async pub/sub support.
|
|
501
489
|
"""
|
|
502
490
|
|
|
503
491
|
__slots__ = ()
|
|
@@ -50,19 +50,39 @@ sqlite_statement_config = StatementConfig(
|
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
class SqliteCursor:
|
|
53
|
-
"""Context manager for SQLite cursor management.
|
|
53
|
+
"""Context manager for SQLite cursor management.
|
|
54
|
+
|
|
55
|
+
Provides automatic cursor creation and cleanup for SQLite database operations.
|
|
56
|
+
"""
|
|
54
57
|
|
|
55
58
|
__slots__ = ("connection", "cursor")
|
|
56
59
|
|
|
57
60
|
def __init__(self, connection: "SqliteConnection") -> None:
|
|
61
|
+
"""Initialize cursor manager.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
connection: SQLite database connection
|
|
65
|
+
"""
|
|
58
66
|
self.connection = connection
|
|
59
67
|
self.cursor: Optional[sqlite3.Cursor] = None
|
|
60
68
|
|
|
61
69
|
def __enter__(self) -> "sqlite3.Cursor":
|
|
70
|
+
"""Create and return a new cursor.
|
|
71
|
+
|
|
72
|
+
Returns:
|
|
73
|
+
Active SQLite cursor object
|
|
74
|
+
"""
|
|
62
75
|
self.cursor = self.connection.cursor()
|
|
63
76
|
return self.cursor
|
|
64
77
|
|
|
65
78
|
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
79
|
+
"""Clean up cursor resources.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
exc_type: Exception type if an exception occurred
|
|
83
|
+
exc_val: Exception value if an exception occurred
|
|
84
|
+
exc_tb: Exception traceback if an exception occurred
|
|
85
|
+
"""
|
|
66
86
|
_ = (exc_type, exc_val, exc_tb)
|
|
67
87
|
if self.cursor is not None:
|
|
68
88
|
with contextlib.suppress(Exception):
|
|
@@ -70,14 +90,33 @@ class SqliteCursor:
|
|
|
70
90
|
|
|
71
91
|
|
|
72
92
|
class SqliteExceptionHandler:
|
|
73
|
-
"""Context manager for handling SQLite database exceptions.
|
|
93
|
+
"""Context manager for handling SQLite database exceptions.
|
|
94
|
+
|
|
95
|
+
Catches SQLite-specific exceptions and converts them to appropriate SQLSpec exceptions.
|
|
96
|
+
"""
|
|
74
97
|
|
|
75
98
|
__slots__ = ()
|
|
76
99
|
|
|
77
100
|
def __enter__(self) -> None:
|
|
78
|
-
|
|
101
|
+
"""Enter exception handling context.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
None
|
|
105
|
+
"""
|
|
106
|
+
return
|
|
79
107
|
|
|
80
108
|
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
109
|
+
"""Handle exceptions and convert to SQLSpec exceptions.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
exc_type: Exception type if an exception occurred
|
|
113
|
+
exc_val: Exception value if an exception occurred
|
|
114
|
+
exc_tb: Exception traceback if an exception occurred
|
|
115
|
+
|
|
116
|
+
Raises:
|
|
117
|
+
SQLSpecError: For general database errors
|
|
118
|
+
SQLParsingError: For SQL syntax or parsing errors
|
|
119
|
+
"""
|
|
81
120
|
if exc_type is None:
|
|
82
121
|
return
|
|
83
122
|
|
|
@@ -129,6 +168,13 @@ class SqliteDriver(SyncDriverAdapterBase):
|
|
|
129
168
|
statement_config: "Optional[StatementConfig]" = None,
|
|
130
169
|
driver_features: "Optional[dict[str, Any]]" = None,
|
|
131
170
|
) -> None:
|
|
171
|
+
"""Initialize SQLite driver.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
connection: SQLite database connection
|
|
175
|
+
statement_config: Statement configuration settings
|
|
176
|
+
driver_features: Driver-specific feature flags
|
|
177
|
+
"""
|
|
132
178
|
if statement_config is None:
|
|
133
179
|
cache_config = get_cache_config()
|
|
134
180
|
statement_config = sqlite_statement_config.replace(
|
|
@@ -141,11 +187,22 @@ class SqliteDriver(SyncDriverAdapterBase):
|
|
|
141
187
|
super().__init__(connection=connection, statement_config=statement_config, driver_features=driver_features)
|
|
142
188
|
|
|
143
189
|
def with_cursor(self, connection: "SqliteConnection") -> "SqliteCursor":
|
|
144
|
-
"""Create context manager for SQLite cursor.
|
|
190
|
+
"""Create context manager for SQLite cursor.
|
|
191
|
+
|
|
192
|
+
Args:
|
|
193
|
+
connection: SQLite database connection
|
|
194
|
+
|
|
195
|
+
Returns:
|
|
196
|
+
Cursor context manager for safe cursor operations
|
|
197
|
+
"""
|
|
145
198
|
return SqliteCursor(connection)
|
|
146
199
|
|
|
147
200
|
def handle_database_exceptions(self) -> "AbstractContextManager[None]":
|
|
148
|
-
"""Handle database-specific exceptions and wrap them appropriately.
|
|
201
|
+
"""Handle database-specific exceptions and wrap them appropriately.
|
|
202
|
+
|
|
203
|
+
Returns:
|
|
204
|
+
Context manager that converts SQLite exceptions to SQLSpec exceptions
|
|
205
|
+
"""
|
|
149
206
|
return SqliteExceptionHandler()
|
|
150
207
|
|
|
151
208
|
def _try_special_handling(self, cursor: "sqlite3.Cursor", statement: "SQL") -> "Optional[SQLResult]":
|
|
@@ -233,7 +290,11 @@ class SqliteDriver(SyncDriverAdapterBase):
|
|
|
233
290
|
return self.create_execution_result(cursor, rowcount_override=affected_rows)
|
|
234
291
|
|
|
235
292
|
def begin(self) -> None:
|
|
236
|
-
"""Begin a database transaction.
|
|
293
|
+
"""Begin a database transaction.
|
|
294
|
+
|
|
295
|
+
Raises:
|
|
296
|
+
SQLSpecError: If transaction cannot be started
|
|
297
|
+
"""
|
|
237
298
|
try:
|
|
238
299
|
if not self.connection.in_transaction:
|
|
239
300
|
self.connection.execute("BEGIN")
|
|
@@ -242,7 +303,11 @@ class SqliteDriver(SyncDriverAdapterBase):
|
|
|
242
303
|
raise SQLSpecError(msg) from e
|
|
243
304
|
|
|
244
305
|
def rollback(self) -> None:
|
|
245
|
-
"""Rollback the current transaction.
|
|
306
|
+
"""Rollback the current transaction.
|
|
307
|
+
|
|
308
|
+
Raises:
|
|
309
|
+
SQLSpecError: If transaction cannot be rolled back
|
|
310
|
+
"""
|
|
246
311
|
try:
|
|
247
312
|
self.connection.rollback()
|
|
248
313
|
except sqlite3.Error as e:
|
|
@@ -250,7 +315,11 @@ class SqliteDriver(SyncDriverAdapterBase):
|
|
|
250
315
|
raise SQLSpecError(msg) from e
|
|
251
316
|
|
|
252
317
|
def commit(self) -> None:
|
|
253
|
-
"""Commit the current transaction.
|
|
318
|
+
"""Commit the current transaction.
|
|
319
|
+
|
|
320
|
+
Raises:
|
|
321
|
+
SQLSpecError: If transaction cannot be committed
|
|
322
|
+
"""
|
|
254
323
|
try:
|
|
255
324
|
self.connection.commit()
|
|
256
325
|
except sqlite3.Error as e:
|
sqlspec/base.py
CHANGED
|
@@ -125,7 +125,7 @@ class SQLSpec:
|
|
|
125
125
|
config: The configuration instance to add.
|
|
126
126
|
|
|
127
127
|
Returns:
|
|
128
|
-
The type of the added configuration
|
|
128
|
+
The type of the added configuration for use as a registry key.
|
|
129
129
|
"""
|
|
130
130
|
config_type = type(config)
|
|
131
131
|
if config_type in self._configs:
|
|
@@ -331,7 +331,6 @@ class SQLSpec:
|
|
|
331
331
|
*args: Positional arguments to pass to the config's provide_connection.
|
|
332
332
|
**kwargs: Keyword arguments to pass to the config's provide_connection.
|
|
333
333
|
|
|
334
|
-
|
|
335
334
|
Returns:
|
|
336
335
|
A sync or async context manager yielding a connection.
|
|
337
336
|
"""
|
|
@@ -564,12 +563,12 @@ class SQLSpec:
|
|
|
564
563
|
"""Update cache configuration with partial values.
|
|
565
564
|
|
|
566
565
|
Args:
|
|
567
|
-
sql_cache_size: Size of the SQL statement cache
|
|
568
|
-
fragment_cache_size: Size of the AST fragment cache
|
|
569
|
-
optimized_cache_size: Size of the optimized expression cache
|
|
570
|
-
sql_cache_enabled: Enable/disable SQL cache
|
|
571
|
-
fragment_cache_enabled: Enable/disable fragment cache
|
|
572
|
-
optimized_cache_enabled: Enable/disable optimized cache
|
|
566
|
+
sql_cache_size: Size of the SQL statement cache.
|
|
567
|
+
fragment_cache_size: Size of the AST fragment cache.
|
|
568
|
+
optimized_cache_size: Size of the optimized expression cache.
|
|
569
|
+
sql_cache_enabled: Enable/disable SQL cache.
|
|
570
|
+
fragment_cache_enabled: Enable/disable fragment cache.
|
|
571
|
+
optimized_cache_enabled: Enable/disable optimized cache.
|
|
573
572
|
"""
|
|
574
573
|
current_config = get_cache_config()
|
|
575
574
|
update_cache_config(
|
|
@@ -627,7 +626,7 @@ class SQLSpec:
|
|
|
627
626
|
"""Get a SQL object by name.
|
|
628
627
|
|
|
629
628
|
Args:
|
|
630
|
-
name: Name of the statement
|
|
629
|
+
name: Name of the statement from SQL file comments.
|
|
631
630
|
Hyphens in names are converted to underscores.
|
|
632
631
|
|
|
633
632
|
Returns:
|
|
@@ -657,7 +656,7 @@ class SQLSpec:
|
|
|
657
656
|
name: Query name to check.
|
|
658
657
|
|
|
659
658
|
Returns:
|
|
660
|
-
True if query exists.
|
|
659
|
+
True if the query exists in the loader.
|
|
661
660
|
"""
|
|
662
661
|
if self._sql_loader is None:
|
|
663
662
|
return False
|
|
@@ -672,7 +671,8 @@ class SQLSpec:
|
|
|
672
671
|
def reload_sql_files(self) -> None:
|
|
673
672
|
"""Reload all SQL files.
|
|
674
673
|
|
|
675
|
-
Note:
|
|
674
|
+
Note:
|
|
675
|
+
This clears the cache and requires calling load_sql_files again.
|
|
676
676
|
"""
|
|
677
677
|
if self._sql_loader is not None:
|
|
678
678
|
self._sql_loader.clear_cache()
|
sqlspec/builder/__init__.py
CHANGED
sqlspec/builder/_base.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Base query builder with validation and parameter binding.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
parameter binding and validation.
|
|
3
|
+
Provides abstract base classes and core functionality for SQL query builders.
|
|
5
4
|
"""
|
|
6
5
|
|
|
7
6
|
from abc import ABC, abstractmethod
|
|
@@ -31,7 +30,7 @@ logger = get_logger(__name__)
|
|
|
31
30
|
|
|
32
31
|
|
|
33
32
|
class SafeQuery:
|
|
34
|
-
"""
|
|
33
|
+
"""SQL query with bound parameters."""
|
|
35
34
|
|
|
36
35
|
__slots__ = ("dialect", "parameters", "sql")
|
|
37
36
|
|
|
@@ -44,7 +43,7 @@ class SafeQuery:
|
|
|
44
43
|
|
|
45
44
|
|
|
46
45
|
class QueryBuilder(ABC):
|
|
47
|
-
"""Abstract base class for SQL query builders
|
|
46
|
+
"""Abstract base class for SQL query builders.
|
|
48
47
|
|
|
49
48
|
Provides common functionality for dialect handling, parameter management,
|
|
50
49
|
and query construction using SQLGlot.
|
sqlspec/builder/_column.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Column expressions for query building.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Provides Column objects that support Python operators for building
|
|
4
|
+
SQL conditions with parameter binding.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from collections.abc import Iterable
|
sqlspec/builder/_ddl.py
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
"""DDL builders
|
|
1
|
+
"""DDL statement builders.
|
|
2
|
+
|
|
3
|
+
Provides builders for DDL operations including CREATE, DROP, ALTER,
|
|
4
|
+
TRUNCATE, and other schema manipulation statements.
|
|
5
|
+
"""
|
|
2
6
|
|
|
3
7
|
from typing import TYPE_CHECKING, Any, Optional, Union
|
|
4
8
|
|
sqlspec/builder/_delete.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""DELETE statement builder.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Provides a fluent interface for building SQL DELETE queries with
|
|
4
|
+
parameter binding and validation.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from typing import Any, Optional
|
|
@@ -19,9 +19,8 @@ __all__ = ("Delete",)
|
|
|
19
19
|
class Delete(QueryBuilder, WhereClauseMixin, ReturningClauseMixin, DeleteFromClauseMixin):
|
|
20
20
|
"""Builder for DELETE statements.
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
operations to maintain cross-dialect compatibility and safety.
|
|
22
|
+
Constructs SQL DELETE statements with parameter binding and validation.
|
|
23
|
+
Does not support JOIN operations to maintain cross-dialect compatibility.
|
|
25
24
|
"""
|
|
26
25
|
|
|
27
26
|
__slots__ = ("_table",)
|
sqlspec/builder/_insert.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""INSERT statement builder.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Provides a fluent interface for building SQL INSERT queries with
|
|
4
|
+
parameter binding and validation.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from typing import TYPE_CHECKING, Any, Final, Optional
|
|
@@ -31,8 +31,7 @@ ERR_MSG_EXPRESSION_NOT_INITIALIZED: Final[str] = "Internal error: base expressio
|
|
|
31
31
|
class Insert(QueryBuilder, ReturningClauseMixin, InsertValuesMixin, InsertFromSelectMixin, InsertIntoClauseMixin):
|
|
32
32
|
"""Builder for INSERT statements.
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
in a safe and dialect-agnostic manner with automatic parameter binding.
|
|
34
|
+
Constructs SQL INSERT queries with parameter binding and validation.
|
|
36
35
|
"""
|
|
37
36
|
|
|
38
37
|
__slots__ = ("_columns", "_table", "_values_added_count")
|
|
@@ -316,8 +315,8 @@ class Insert(QueryBuilder, ReturningClauseMixin, InsertValuesMixin, InsertFromSe
|
|
|
316
315
|
class ConflictBuilder:
|
|
317
316
|
"""Builder for ON CONFLICT clauses in INSERT statements.
|
|
318
317
|
|
|
319
|
-
|
|
320
|
-
|
|
318
|
+
Constructs conflict resolution clauses using PostgreSQL-style syntax,
|
|
319
|
+
which SQLGlot can transpile to other dialects.
|
|
321
320
|
"""
|
|
322
321
|
|
|
323
322
|
__slots__ = ("_columns", "_insert_builder")
|
sqlspec/builder/_merge.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""MERGE statement builder.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Provides a fluent interface for building SQL MERGE queries with
|
|
4
|
+
parameter binding and validation.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from typing import Any, Optional
|
|
@@ -33,8 +33,8 @@ class Merge(
|
|
|
33
33
|
):
|
|
34
34
|
"""Builder for MERGE statements.
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
Constructs SQL MERGE statements (also known as UPSERT in some databases)
|
|
37
|
+
with parameter binding and validation.
|
|
38
38
|
"""
|
|
39
39
|
|
|
40
40
|
__slots__ = ()
|