sqlspec 0.11.0__py3-none-any.whl → 0.11.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sqlspec might be problematic. Click here for more details.
- sqlspec/adapters/adbc/driver.py +37 -60
- sqlspec/adapters/aiosqlite/driver.py +73 -104
- sqlspec/adapters/asyncmy/driver.py +28 -44
- sqlspec/adapters/asyncpg/driver.py +34 -44
- sqlspec/adapters/bigquery/driver.py +79 -168
- sqlspec/adapters/duckdb/driver.py +20 -49
- sqlspec/adapters/oracledb/driver.py +66 -86
- sqlspec/adapters/psqlpy/driver.py +39 -56
- sqlspec/adapters/psycopg/driver.py +71 -112
- sqlspec/adapters/sqlite/driver.py +15 -35
- sqlspec/base.py +0 -41
- sqlspec/filters.py +2 -1
- sqlspec/mixins.py +9 -10
- {sqlspec-0.11.0.dist-info → sqlspec-0.11.1.dist-info}/METADATA +4 -1
- {sqlspec-0.11.0.dist-info → sqlspec-0.11.1.dist-info}/RECORD +18 -18
- {sqlspec-0.11.0.dist-info → sqlspec-0.11.1.dist-info}/WHEEL +0 -0
- {sqlspec-0.11.0.dist-info → sqlspec-0.11.1.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.11.0.dist-info → sqlspec-0.11.1.dist-info}/licenses/NOTICE +0 -0
|
@@ -6,14 +6,14 @@ import aiosqlite
|
|
|
6
6
|
from sqlglot import exp
|
|
7
7
|
|
|
8
8
|
from sqlspec.base import AsyncDriverAdapterProtocol
|
|
9
|
+
from sqlspec.filters import StatementFilter
|
|
9
10
|
from sqlspec.mixins import ResultConverter, SQLTranslatorMixin
|
|
10
11
|
from sqlspec.statement import SQLStatement
|
|
11
12
|
from sqlspec.typing import is_dict
|
|
12
13
|
|
|
13
14
|
if TYPE_CHECKING:
|
|
14
|
-
from collections.abc import AsyncGenerator, Sequence
|
|
15
|
+
from collections.abc import AsyncGenerator, Mapping, Sequence # Added Mapping, Sequence
|
|
15
16
|
|
|
16
|
-
from sqlspec.filters import StatementFilter
|
|
17
17
|
from sqlspec.typing import ModelDTOT, StatementParameterType, T
|
|
18
18
|
|
|
19
19
|
__all__ = ("AiosqliteConnection", "AiosqliteDriver")
|
|
@@ -51,7 +51,6 @@ class AiosqliteDriver(
|
|
|
51
51
|
self,
|
|
52
52
|
sql: str,
|
|
53
53
|
parameters: "Optional[StatementParameterType]" = None,
|
|
54
|
-
/,
|
|
55
54
|
*filters: "StatementFilter",
|
|
56
55
|
**kwargs: Any,
|
|
57
56
|
) -> "tuple[str, Optional[Union[tuple[Any, ...], list[Any], dict[str, Any]]]]":
|
|
@@ -63,17 +62,27 @@ class AiosqliteDriver(
|
|
|
63
62
|
|
|
64
63
|
Args:
|
|
65
64
|
sql: SQL statement.
|
|
66
|
-
parameters: Query parameters.
|
|
65
|
+
parameters: Query parameters. Can be data or a StatementFilter.
|
|
67
66
|
*filters: Statement filters to apply.
|
|
68
67
|
**kwargs: Additional keyword arguments.
|
|
69
68
|
|
|
70
69
|
Returns:
|
|
71
70
|
Tuple of processed SQL and parameters.
|
|
72
71
|
"""
|
|
73
|
-
|
|
72
|
+
passed_parameters: Optional[Union[Mapping[str, Any], Sequence[Any]]] = None
|
|
73
|
+
combined_filters_list: list[StatementFilter] = list(filters)
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
if parameters is not None:
|
|
76
|
+
if isinstance(parameters, StatementFilter):
|
|
77
|
+
combined_filters_list.insert(0, parameters)
|
|
78
|
+
# _actual_data_params remains None
|
|
79
|
+
else:
|
|
80
|
+
# If parameters is not a StatementFilter, it's actual data parameters.
|
|
81
|
+
passed_parameters = parameters
|
|
82
|
+
|
|
83
|
+
statement = SQLStatement(sql, passed_parameters, kwargs=kwargs, dialect=self.dialect)
|
|
84
|
+
|
|
85
|
+
for filter_obj in combined_filters_list:
|
|
77
86
|
statement = statement.apply_filter(filter_obj)
|
|
78
87
|
|
|
79
88
|
processed_sql, processed_params, parsed_expr = statement.process()
|
|
@@ -121,7 +130,6 @@ class AiosqliteDriver(
|
|
|
121
130
|
self,
|
|
122
131
|
sql: str,
|
|
123
132
|
parameters: "Optional[StatementParameterType]" = None,
|
|
124
|
-
/,
|
|
125
133
|
*filters: "StatementFilter",
|
|
126
134
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
127
135
|
schema_type: None = None,
|
|
@@ -132,7 +140,6 @@ class AiosqliteDriver(
|
|
|
132
140
|
self,
|
|
133
141
|
sql: str,
|
|
134
142
|
parameters: "Optional[StatementParameterType]" = None,
|
|
135
|
-
/,
|
|
136
143
|
*filters: "StatementFilter",
|
|
137
144
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
138
145
|
schema_type: "type[ModelDTOT]",
|
|
@@ -142,7 +149,6 @@ class AiosqliteDriver(
|
|
|
142
149
|
self,
|
|
143
150
|
sql: str,
|
|
144
151
|
parameters: "Optional[StatementParameterType]" = None,
|
|
145
|
-
/,
|
|
146
152
|
*filters: "StatementFilter",
|
|
147
153
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
148
154
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
@@ -156,25 +162,19 @@ class AiosqliteDriver(
|
|
|
156
162
|
connection = self._connection(connection)
|
|
157
163
|
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
158
164
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
column_names = [column[0] for column in cursor.description]
|
|
167
|
-
|
|
168
|
-
# Convert to dicts first
|
|
169
|
-
dict_results = [dict(zip(column_names, row)) for row in results]
|
|
170
|
-
return self.to_schema(dict_results, schema_type=schema_type)
|
|
165
|
+
async with self._with_cursor(connection) as cursor:
|
|
166
|
+
await cursor.execute(sql, parameters or ())
|
|
167
|
+
results = await cursor.fetchall()
|
|
168
|
+
if not results:
|
|
169
|
+
return []
|
|
170
|
+
column_names = [column[0] for column in cursor.description]
|
|
171
|
+
return self.to_schema([dict(zip(column_names, row)) for row in results], schema_type=schema_type)
|
|
171
172
|
|
|
172
173
|
@overload
|
|
173
174
|
async def select_one(
|
|
174
175
|
self,
|
|
175
176
|
sql: str,
|
|
176
177
|
parameters: "Optional[StatementParameterType]" = None,
|
|
177
|
-
/,
|
|
178
178
|
*filters: "StatementFilter",
|
|
179
179
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
180
180
|
schema_type: None = None,
|
|
@@ -185,7 +185,6 @@ class AiosqliteDriver(
|
|
|
185
185
|
self,
|
|
186
186
|
sql: str,
|
|
187
187
|
parameters: "Optional[StatementParameterType]" = None,
|
|
188
|
-
/,
|
|
189
188
|
*filters: "StatementFilter",
|
|
190
189
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
191
190
|
schema_type: "type[ModelDTOT]",
|
|
@@ -195,7 +194,6 @@ class AiosqliteDriver(
|
|
|
195
194
|
self,
|
|
196
195
|
sql: str,
|
|
197
196
|
parameters: "Optional[StatementParameterType]" = None,
|
|
198
|
-
/,
|
|
199
197
|
*filters: "StatementFilter",
|
|
200
198
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
201
199
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
@@ -209,24 +207,20 @@ class AiosqliteDriver(
|
|
|
209
207
|
connection = self._connection(connection)
|
|
210
208
|
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
211
209
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
# Get column names
|
|
218
|
-
column_names = [column[0] for column in cursor.description]
|
|
210
|
+
async with self._with_cursor(connection) as cursor:
|
|
211
|
+
await cursor.execute(sql, parameters or ())
|
|
212
|
+
result = await cursor.fetchone()
|
|
213
|
+
result = self.check_not_found(result)
|
|
219
214
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
215
|
+
# Get column names
|
|
216
|
+
column_names = [column[0] for column in cursor.description]
|
|
217
|
+
return self.to_schema(dict(zip(column_names, result)), schema_type=schema_type)
|
|
223
218
|
|
|
224
219
|
@overload
|
|
225
220
|
async def select_one_or_none(
|
|
226
221
|
self,
|
|
227
222
|
sql: str,
|
|
228
223
|
parameters: "Optional[StatementParameterType]" = None,
|
|
229
|
-
/,
|
|
230
224
|
*filters: "StatementFilter",
|
|
231
225
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
232
226
|
schema_type: None = None,
|
|
@@ -237,7 +231,6 @@ class AiosqliteDriver(
|
|
|
237
231
|
self,
|
|
238
232
|
sql: str,
|
|
239
233
|
parameters: "Optional[StatementParameterType]" = None,
|
|
240
|
-
/,
|
|
241
234
|
*filters: "StatementFilter",
|
|
242
235
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
243
236
|
schema_type: "type[ModelDTOT]",
|
|
@@ -247,7 +240,6 @@ class AiosqliteDriver(
|
|
|
247
240
|
self,
|
|
248
241
|
sql: str,
|
|
249
242
|
parameters: "Optional[StatementParameterType]" = None,
|
|
250
|
-
/,
|
|
251
243
|
*filters: "StatementFilter",
|
|
252
244
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
253
245
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
@@ -261,25 +253,19 @@ class AiosqliteDriver(
|
|
|
261
253
|
connection = self._connection(connection)
|
|
262
254
|
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
263
255
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
column_names = [column[0] for column in cursor.description]
|
|
272
|
-
|
|
273
|
-
# Convert to dict and then use ResultConverter
|
|
274
|
-
dict_result = dict(zip(column_names, result))
|
|
275
|
-
return self.to_schema(dict_result, schema_type=schema_type)
|
|
256
|
+
async with self._with_cursor(connection) as cursor:
|
|
257
|
+
await cursor.execute(sql, parameters or ())
|
|
258
|
+
result = await cursor.fetchone()
|
|
259
|
+
if result is None:
|
|
260
|
+
return None
|
|
261
|
+
column_names = [column[0] for column in cursor.description]
|
|
262
|
+
return self.to_schema(dict(zip(column_names, result)), schema_type=schema_type)
|
|
276
263
|
|
|
277
264
|
@overload
|
|
278
265
|
async def select_value(
|
|
279
266
|
self,
|
|
280
267
|
sql: str,
|
|
281
268
|
parameters: "Optional[StatementParameterType]" = None,
|
|
282
|
-
/,
|
|
283
269
|
*filters: "StatementFilter",
|
|
284
270
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
285
271
|
schema_type: None = None,
|
|
@@ -290,7 +276,6 @@ class AiosqliteDriver(
|
|
|
290
276
|
self,
|
|
291
277
|
sql: str,
|
|
292
278
|
parameters: "Optional[StatementParameterType]" = None,
|
|
293
|
-
/,
|
|
294
279
|
*filters: "StatementFilter",
|
|
295
280
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
296
281
|
schema_type: "type[T]",
|
|
@@ -300,7 +285,6 @@ class AiosqliteDriver(
|
|
|
300
285
|
self,
|
|
301
286
|
sql: str,
|
|
302
287
|
parameters: "Optional[StatementParameterType]" = None,
|
|
303
|
-
/,
|
|
304
288
|
*filters: "StatementFilter",
|
|
305
289
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
306
290
|
schema_type: "Optional[type[T]]" = None,
|
|
@@ -314,23 +298,22 @@ class AiosqliteDriver(
|
|
|
314
298
|
connection = self._connection(connection)
|
|
315
299
|
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
316
300
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
301
|
+
async with self._with_cursor(connection) as cursor:
|
|
302
|
+
await cursor.execute(sql, parameters or ())
|
|
303
|
+
result = await cursor.fetchone()
|
|
304
|
+
result = self.check_not_found(result)
|
|
321
305
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
306
|
+
# Return first value from the row
|
|
307
|
+
result_value = result[0]
|
|
308
|
+
if schema_type is None:
|
|
309
|
+
return result_value
|
|
310
|
+
return schema_type(result_value) # type: ignore[call-arg]
|
|
327
311
|
|
|
328
312
|
@overload
|
|
329
313
|
async def select_value_or_none(
|
|
330
314
|
self,
|
|
331
315
|
sql: str,
|
|
332
316
|
parameters: "Optional[StatementParameterType]" = None,
|
|
333
|
-
/,
|
|
334
317
|
*filters: "StatementFilter",
|
|
335
318
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
336
319
|
schema_type: None = None,
|
|
@@ -341,7 +324,6 @@ class AiosqliteDriver(
|
|
|
341
324
|
self,
|
|
342
325
|
sql: str,
|
|
343
326
|
parameters: "Optional[StatementParameterType]" = None,
|
|
344
|
-
/,
|
|
345
327
|
*filters: "StatementFilter",
|
|
346
328
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
347
329
|
schema_type: "type[T]",
|
|
@@ -351,7 +333,6 @@ class AiosqliteDriver(
|
|
|
351
333
|
self,
|
|
352
334
|
sql: str,
|
|
353
335
|
parameters: "Optional[StatementParameterType]" = None,
|
|
354
|
-
/,
|
|
355
336
|
*filters: "StatementFilter",
|
|
356
337
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
357
338
|
schema_type: "Optional[type[T]]" = None,
|
|
@@ -365,23 +346,21 @@ class AiosqliteDriver(
|
|
|
365
346
|
connection = self._connection(connection)
|
|
366
347
|
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
367
348
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
return result_value
|
|
378
|
-
return schema_type(result_value) # type: ignore[call-arg]
|
|
349
|
+
async with self._with_cursor(connection) as cursor:
|
|
350
|
+
# Execute the query
|
|
351
|
+
await cursor.execute(sql, parameters or ())
|
|
352
|
+
result = await cursor.fetchone()
|
|
353
|
+
if result is None:
|
|
354
|
+
return None
|
|
355
|
+
result_value = result[0]
|
|
356
|
+
if schema_type is None:
|
|
357
|
+
return result_value
|
|
358
|
+
return schema_type(result_value) # type: ignore[call-arg]
|
|
379
359
|
|
|
380
360
|
async def insert_update_delete(
|
|
381
361
|
self,
|
|
382
362
|
sql: str,
|
|
383
363
|
parameters: "Optional[StatementParameterType]" = None,
|
|
384
|
-
/,
|
|
385
364
|
*filters: "StatementFilter",
|
|
386
365
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
387
366
|
**kwargs: Any,
|
|
@@ -393,18 +372,16 @@ class AiosqliteDriver(
|
|
|
393
372
|
"""
|
|
394
373
|
connection = self._connection(connection)
|
|
395
374
|
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
return cursor.rowcount
|
|
375
|
+
async with self._with_cursor(connection) as cursor:
|
|
376
|
+
# Execute the query
|
|
377
|
+
await cursor.execute(sql, parameters or ())
|
|
378
|
+
return cursor.rowcount
|
|
401
379
|
|
|
402
380
|
@overload
|
|
403
381
|
async def insert_update_delete_returning(
|
|
404
382
|
self,
|
|
405
383
|
sql: str,
|
|
406
384
|
parameters: "Optional[StatementParameterType]" = None,
|
|
407
|
-
/,
|
|
408
385
|
*filters: "StatementFilter",
|
|
409
386
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
410
387
|
schema_type: None = None,
|
|
@@ -415,7 +392,6 @@ class AiosqliteDriver(
|
|
|
415
392
|
self,
|
|
416
393
|
sql: str,
|
|
417
394
|
parameters: "Optional[StatementParameterType]" = None,
|
|
418
|
-
/,
|
|
419
395
|
*filters: "StatementFilter",
|
|
420
396
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
421
397
|
schema_type: "type[ModelDTOT]",
|
|
@@ -425,7 +401,6 @@ class AiosqliteDriver(
|
|
|
425
401
|
self,
|
|
426
402
|
sql: str,
|
|
427
403
|
parameters: "Optional[StatementParameterType]" = None,
|
|
428
|
-
/,
|
|
429
404
|
*filters: "StatementFilter",
|
|
430
405
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
431
406
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
@@ -439,26 +414,18 @@ class AiosqliteDriver(
|
|
|
439
414
|
connection = self._connection(connection)
|
|
440
415
|
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
441
416
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
# Get column names
|
|
451
|
-
column_names = [column[0] for column in cursor.description]
|
|
452
|
-
|
|
453
|
-
# Convert to dict and then use ResultConverter
|
|
454
|
-
dict_result = dict(zip(column_names, result))
|
|
455
|
-
return self.to_schema(dict_result, schema_type=schema_type)
|
|
417
|
+
async with self._with_cursor(connection) as cursor:
|
|
418
|
+
# Execute the query
|
|
419
|
+
await cursor.execute(sql, parameters or ())
|
|
420
|
+
result = await cursor.fetchone()
|
|
421
|
+
result = self.check_not_found(result)
|
|
422
|
+
column_names = [column[0] for column in cursor.description]
|
|
423
|
+
return self.to_schema(dict(zip(column_names, result)), schema_type=schema_type)
|
|
456
424
|
|
|
457
425
|
async def execute_script(
|
|
458
426
|
self,
|
|
459
427
|
sql: str,
|
|
460
428
|
parameters: "Optional[StatementParameterType]" = None,
|
|
461
|
-
/,
|
|
462
429
|
connection: "Optional[AiosqliteConnection]" = None,
|
|
463
430
|
**kwargs: Any,
|
|
464
431
|
) -> str:
|
|
@@ -470,10 +437,12 @@ class AiosqliteDriver(
|
|
|
470
437
|
connection = self._connection(connection)
|
|
471
438
|
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
472
439
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
440
|
+
async with self._with_cursor(connection) as cursor:
|
|
441
|
+
if parameters:
|
|
442
|
+
await cursor.execute(sql, parameters)
|
|
443
|
+
else:
|
|
444
|
+
await cursor.executescript(sql)
|
|
445
|
+
return "DONE"
|
|
477
446
|
|
|
478
447
|
def _connection(self, connection: "Optional[AiosqliteConnection]" = None) -> "AiosqliteConnection":
|
|
479
448
|
"""Get the connection to use for the operation.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# type: ignore
|
|
2
2
|
import logging
|
|
3
3
|
import re
|
|
4
|
-
from collections.abc import AsyncGenerator
|
|
4
|
+
from collections.abc import AsyncGenerator
|
|
5
5
|
from contextlib import asynccontextmanager
|
|
6
6
|
from typing import TYPE_CHECKING, Any, Optional, Union, overload
|
|
7
7
|
|
|
@@ -9,14 +9,16 @@ from asyncmy import Connection
|
|
|
9
9
|
|
|
10
10
|
from sqlspec.base import AsyncDriverAdapterProtocol
|
|
11
11
|
from sqlspec.exceptions import ParameterStyleMismatchError
|
|
12
|
+
from sqlspec.filters import StatementFilter
|
|
12
13
|
from sqlspec.mixins import ResultConverter, SQLTranslatorMixin
|
|
13
14
|
from sqlspec.statement import SQLStatement
|
|
14
15
|
from sqlspec.typing import is_dict
|
|
15
16
|
|
|
16
17
|
if TYPE_CHECKING:
|
|
18
|
+
from collections.abc import Mapping, Sequence
|
|
19
|
+
|
|
17
20
|
from asyncmy.cursors import Cursor
|
|
18
21
|
|
|
19
|
-
from sqlspec.filters import StatementFilter
|
|
20
22
|
from sqlspec.typing import ModelDTOT, StatementParameterType, T
|
|
21
23
|
|
|
22
24
|
__all__ = ("AsyncmyDriver",)
|
|
@@ -55,7 +57,6 @@ class AsyncmyDriver(
|
|
|
55
57
|
self,
|
|
56
58
|
sql: str,
|
|
57
59
|
parameters: "Optional[StatementParameterType]" = None,
|
|
58
|
-
/,
|
|
59
60
|
*filters: "StatementFilter",
|
|
60
61
|
**kwargs: Any,
|
|
61
62
|
) -> "tuple[str, Optional[Union[tuple[Any, ...], list[Any], dict[str, Any]]]]":
|
|
@@ -63,7 +64,7 @@ class AsyncmyDriver(
|
|
|
63
64
|
|
|
64
65
|
Args:
|
|
65
66
|
sql: The SQL statement to process.
|
|
66
|
-
parameters: The parameters to bind to the statement.
|
|
67
|
+
parameters: The parameters to bind to the statement. Can be data or a StatementFilter.
|
|
67
68
|
*filters: Statement filters to apply.
|
|
68
69
|
**kwargs: Additional keyword arguments.
|
|
69
70
|
|
|
@@ -73,41 +74,52 @@ class AsyncmyDriver(
|
|
|
73
74
|
Returns:
|
|
74
75
|
A tuple of (sql, parameters) ready for execution.
|
|
75
76
|
"""
|
|
77
|
+
# Convert filters tuple to a list to allow modification
|
|
78
|
+
current_filters: list[StatementFilter] = list(filters)
|
|
79
|
+
actual_parameters: Optional[Union[Mapping[str, Any], Sequence[Any]]] = None
|
|
80
|
+
|
|
81
|
+
if parameters is not None:
|
|
82
|
+
if isinstance(parameters, StatementFilter):
|
|
83
|
+
current_filters.insert(0, parameters)
|
|
84
|
+
# actual_parameters remains None
|
|
85
|
+
else:
|
|
86
|
+
actual_parameters = parameters # type: ignore[assignment]
|
|
87
|
+
|
|
76
88
|
# Handle MySQL-specific placeholders (%s) which SQLGlot doesn't parse well
|
|
77
89
|
# If %s placeholders are present, handle them directly
|
|
78
90
|
mysql_placeholders_count = len(MYSQL_PLACEHOLDER_PATTERN.findall(sql))
|
|
79
91
|
|
|
80
92
|
if mysql_placeholders_count > 0:
|
|
81
93
|
# For MySQL format placeholders, minimal processing is needed
|
|
82
|
-
if
|
|
94
|
+
if actual_parameters is None:
|
|
83
95
|
if mysql_placeholders_count > 0:
|
|
84
96
|
msg = f"asyncmy: SQL statement contains {mysql_placeholders_count} format placeholders ('%s'), but no parameters were provided. SQL: {sql}"
|
|
85
97
|
raise ParameterStyleMismatchError(msg)
|
|
86
98
|
return sql, None
|
|
87
99
|
|
|
88
100
|
# Convert dict to tuple if needed
|
|
89
|
-
if is_dict(
|
|
101
|
+
if is_dict(actual_parameters):
|
|
90
102
|
# MySQL's %s placeholders require positional params
|
|
91
103
|
msg = "asyncmy: Dictionary parameters provided with '%s' placeholders. MySQL format placeholders require tuple/list parameters."
|
|
92
104
|
raise ParameterStyleMismatchError(msg)
|
|
93
105
|
|
|
94
106
|
# Convert to tuple (handles both scalar and sequence cases)
|
|
95
|
-
if not isinstance(
|
|
107
|
+
if not isinstance(actual_parameters, (list, tuple)):
|
|
96
108
|
# Scalar parameter case
|
|
97
|
-
return sql, (
|
|
109
|
+
return sql, (actual_parameters,)
|
|
98
110
|
|
|
99
111
|
# Sequence parameter case - ensure appropriate length
|
|
100
|
-
if len(
|
|
101
|
-
msg = f"asyncmy: Parameter count mismatch. SQL expects {mysql_placeholders_count} '%s' placeholders, but {len(
|
|
112
|
+
if len(actual_parameters) != mysql_placeholders_count: # type: ignore[arg-type]
|
|
113
|
+
msg = f"asyncmy: Parameter count mismatch. SQL expects {mysql_placeholders_count} '%s' placeholders, but {len(actual_parameters)} parameters were provided. SQL: {sql}" # type: ignore[arg-type]
|
|
102
114
|
raise ParameterStyleMismatchError(msg)
|
|
103
115
|
|
|
104
|
-
return sql, tuple(
|
|
116
|
+
return sql, tuple(actual_parameters) # type: ignore[arg-type]
|
|
105
117
|
|
|
106
118
|
# Create a SQLStatement with MySQL dialect
|
|
107
|
-
statement = SQLStatement(sql,
|
|
119
|
+
statement = SQLStatement(sql, actual_parameters, kwargs=kwargs, dialect=self.dialect)
|
|
108
120
|
|
|
109
121
|
# Apply any filters
|
|
110
|
-
for filter_obj in filters
|
|
122
|
+
for filter_obj in current_filters: # Use the modified list of filters
|
|
111
123
|
statement = statement.apply_filter(filter_obj)
|
|
112
124
|
|
|
113
125
|
# Process the statement for execution
|
|
@@ -136,7 +148,6 @@ class AsyncmyDriver(
|
|
|
136
148
|
self,
|
|
137
149
|
sql: str,
|
|
138
150
|
parameters: "Optional[StatementParameterType]" = None,
|
|
139
|
-
/,
|
|
140
151
|
*filters: "StatementFilter",
|
|
141
152
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
142
153
|
schema_type: None = None,
|
|
@@ -147,7 +158,6 @@ class AsyncmyDriver(
|
|
|
147
158
|
self,
|
|
148
159
|
sql: str,
|
|
149
160
|
parameters: "Optional[StatementParameterType]" = None,
|
|
150
|
-
/,
|
|
151
161
|
*filters: "StatementFilter",
|
|
152
162
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
153
163
|
schema_type: "type[ModelDTOT]",
|
|
@@ -157,7 +167,6 @@ class AsyncmyDriver(
|
|
|
157
167
|
self,
|
|
158
168
|
sql: str,
|
|
159
169
|
parameters: "Optional[StatementParameterType]" = None,
|
|
160
|
-
/,
|
|
161
170
|
*filters: "StatementFilter",
|
|
162
171
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
163
172
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
@@ -176,17 +185,13 @@ class AsyncmyDriver(
|
|
|
176
185
|
if not results:
|
|
177
186
|
return []
|
|
178
187
|
column_names = [c[0] for c in cursor.description or []]
|
|
179
|
-
|
|
180
|
-
# Convert to dicts first
|
|
181
|
-
dict_results = [dict(zip(column_names, row)) for row in results]
|
|
182
|
-
return self.to_schema(dict_results, schema_type=schema_type)
|
|
188
|
+
return self.to_schema([dict(zip(column_names, row)) for row in results], schema_type=schema_type)
|
|
183
189
|
|
|
184
190
|
@overload
|
|
185
191
|
async def select_one(
|
|
186
192
|
self,
|
|
187
193
|
sql: str,
|
|
188
194
|
parameters: "Optional[StatementParameterType]" = None,
|
|
189
|
-
/,
|
|
190
195
|
*filters: "StatementFilter",
|
|
191
196
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
192
197
|
schema_type: None = None,
|
|
@@ -197,7 +202,6 @@ class AsyncmyDriver(
|
|
|
197
202
|
self,
|
|
198
203
|
sql: str,
|
|
199
204
|
parameters: "Optional[StatementParameterType]" = None,
|
|
200
|
-
/,
|
|
201
205
|
*filters: "StatementFilter",
|
|
202
206
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
203
207
|
schema_type: "type[ModelDTOT]",
|
|
@@ -207,7 +211,6 @@ class AsyncmyDriver(
|
|
|
207
211
|
self,
|
|
208
212
|
sql: str,
|
|
209
213
|
parameters: "Optional[StatementParameterType]" = None,
|
|
210
|
-
/,
|
|
211
214
|
*filters: "StatementFilter",
|
|
212
215
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
213
216
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
@@ -225,17 +228,13 @@ class AsyncmyDriver(
|
|
|
225
228
|
result = await cursor.fetchone()
|
|
226
229
|
result = self.check_not_found(result)
|
|
227
230
|
column_names = [c[0] for c in cursor.description or []]
|
|
228
|
-
|
|
229
|
-
# Convert to dict and use ResultConverter
|
|
230
|
-
dict_result = dict(zip(column_names, result))
|
|
231
|
-
return self.to_schema(dict_result, schema_type=schema_type)
|
|
231
|
+
return self.to_schema(dict(zip(column_names, result)), schema_type=schema_type)
|
|
232
232
|
|
|
233
233
|
@overload
|
|
234
234
|
async def select_one_or_none(
|
|
235
235
|
self,
|
|
236
236
|
sql: str,
|
|
237
237
|
parameters: "Optional[StatementParameterType]" = None,
|
|
238
|
-
/,
|
|
239
238
|
*filters: "StatementFilter",
|
|
240
239
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
241
240
|
schema_type: None = None,
|
|
@@ -246,7 +245,6 @@ class AsyncmyDriver(
|
|
|
246
245
|
self,
|
|
247
246
|
sql: str,
|
|
248
247
|
parameters: "Optional[StatementParameterType]" = None,
|
|
249
|
-
/,
|
|
250
248
|
*filters: "StatementFilter",
|
|
251
249
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
252
250
|
schema_type: "type[ModelDTOT]",
|
|
@@ -256,7 +254,6 @@ class AsyncmyDriver(
|
|
|
256
254
|
self,
|
|
257
255
|
sql: str,
|
|
258
256
|
parameters: "Optional[StatementParameterType]" = None,
|
|
259
|
-
/,
|
|
260
257
|
*filters: "StatementFilter",
|
|
261
258
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
262
259
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
@@ -275,17 +272,13 @@ class AsyncmyDriver(
|
|
|
275
272
|
if result is None:
|
|
276
273
|
return None
|
|
277
274
|
column_names = [c[0] for c in cursor.description or []]
|
|
278
|
-
|
|
279
|
-
# Convert to dict and use ResultConverter
|
|
280
|
-
dict_result = dict(zip(column_names, result))
|
|
281
|
-
return self.to_schema(dict_result, schema_type=schema_type)
|
|
275
|
+
return self.to_schema(dict(zip(column_names, result)), schema_type=schema_type)
|
|
282
276
|
|
|
283
277
|
@overload
|
|
284
278
|
async def select_value(
|
|
285
279
|
self,
|
|
286
280
|
sql: str,
|
|
287
281
|
parameters: "Optional[StatementParameterType]" = None,
|
|
288
|
-
/,
|
|
289
282
|
*filters: "StatementFilter",
|
|
290
283
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
291
284
|
schema_type: None = None,
|
|
@@ -296,7 +289,6 @@ class AsyncmyDriver(
|
|
|
296
289
|
self,
|
|
297
290
|
sql: str,
|
|
298
291
|
parameters: "Optional[StatementParameterType]" = None,
|
|
299
|
-
/,
|
|
300
292
|
*filters: "StatementFilter",
|
|
301
293
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
302
294
|
schema_type: "type[T]",
|
|
@@ -306,7 +298,6 @@ class AsyncmyDriver(
|
|
|
306
298
|
self,
|
|
307
299
|
sql: str,
|
|
308
300
|
parameters: "Optional[StatementParameterType]" = None,
|
|
309
|
-
/,
|
|
310
301
|
*filters: "StatementFilter",
|
|
311
302
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
312
303
|
schema_type: "Optional[type[T]]" = None,
|
|
@@ -333,7 +324,6 @@ class AsyncmyDriver(
|
|
|
333
324
|
self,
|
|
334
325
|
sql: str,
|
|
335
326
|
parameters: "Optional[StatementParameterType]" = None,
|
|
336
|
-
/,
|
|
337
327
|
*filters: "StatementFilter",
|
|
338
328
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
339
329
|
schema_type: None = None,
|
|
@@ -344,7 +334,6 @@ class AsyncmyDriver(
|
|
|
344
334
|
self,
|
|
345
335
|
sql: str,
|
|
346
336
|
parameters: "Optional[StatementParameterType]" = None,
|
|
347
|
-
/,
|
|
348
337
|
*filters: "StatementFilter",
|
|
349
338
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
350
339
|
schema_type: "type[T]",
|
|
@@ -354,7 +343,6 @@ class AsyncmyDriver(
|
|
|
354
343
|
self,
|
|
355
344
|
sql: str,
|
|
356
345
|
parameters: "Optional[StatementParameterType]" = None,
|
|
357
|
-
/,
|
|
358
346
|
*filters: "StatementFilter",
|
|
359
347
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
360
348
|
schema_type: "Optional[type[T]]" = None,
|
|
@@ -381,7 +369,6 @@ class AsyncmyDriver(
|
|
|
381
369
|
self,
|
|
382
370
|
sql: str,
|
|
383
371
|
parameters: "Optional[StatementParameterType]" = None,
|
|
384
|
-
/,
|
|
385
372
|
*filters: "StatementFilter",
|
|
386
373
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
387
374
|
**kwargs: Any,
|
|
@@ -402,7 +389,6 @@ class AsyncmyDriver(
|
|
|
402
389
|
self,
|
|
403
390
|
sql: str,
|
|
404
391
|
parameters: "Optional[StatementParameterType]" = None,
|
|
405
|
-
/,
|
|
406
392
|
*filters: "StatementFilter",
|
|
407
393
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
408
394
|
schema_type: None = None,
|
|
@@ -413,7 +399,6 @@ class AsyncmyDriver(
|
|
|
413
399
|
self,
|
|
414
400
|
sql: str,
|
|
415
401
|
parameters: "Optional[StatementParameterType]" = None,
|
|
416
|
-
/,
|
|
417
402
|
*filters: "StatementFilter",
|
|
418
403
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
419
404
|
schema_type: "type[ModelDTOT]",
|
|
@@ -423,7 +408,6 @@ class AsyncmyDriver(
|
|
|
423
408
|
self,
|
|
424
409
|
sql: str,
|
|
425
410
|
parameters: "Optional[StatementParameterType]" = None,
|
|
426
|
-
/,
|
|
427
411
|
*filters: "StatementFilter",
|
|
428
412
|
connection: "Optional[AsyncmyConnection]" = None,
|
|
429
413
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|