sqlspec 0.10.1__py3-none-any.whl → 0.11.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.

@@ -1,23 +1,31 @@
1
+ import logging
1
2
  from contextlib import asynccontextmanager
2
- from typing import TYPE_CHECKING, Any, Optional, Union, cast, overload
3
+ from typing import TYPE_CHECKING, Any, Optional, Union, overload
3
4
 
4
5
  import aiosqlite
6
+ from sqlglot import exp
5
7
 
6
8
  from sqlspec.base import AsyncDriverAdapterProtocol
7
- from sqlspec.mixins import SQLTranslatorMixin
9
+ from sqlspec.mixins import ResultConverter, SQLTranslatorMixin
10
+ from sqlspec.statement import SQLStatement
11
+ from sqlspec.typing import is_dict
8
12
 
9
13
  if TYPE_CHECKING:
10
14
  from collections.abc import AsyncGenerator, Sequence
11
15
 
16
+ from sqlspec.filters import StatementFilter
12
17
  from sqlspec.typing import ModelDTOT, StatementParameterType, T
13
18
 
14
19
  __all__ = ("AiosqliteConnection", "AiosqliteDriver")
15
20
  AiosqliteConnection = aiosqlite.Connection
16
21
 
22
+ logger = logging.getLogger("sqlspec")
23
+
17
24
 
18
25
  class AiosqliteDriver(
19
26
  SQLTranslatorMixin["AiosqliteConnection"],
20
27
  AsyncDriverAdapterProtocol["AiosqliteConnection"],
28
+ ResultConverter,
21
29
  ):
22
30
  """SQLite Async Driver Adapter."""
23
31
 
@@ -39,6 +47,74 @@ class AiosqliteDriver(
39
47
  finally:
40
48
  await cursor.close()
41
49
 
50
+ def _process_sql_params(
51
+ self,
52
+ sql: str,
53
+ parameters: "Optional[StatementParameterType]" = None,
54
+ /,
55
+ *filters: "StatementFilter",
56
+ **kwargs: Any,
57
+ ) -> "tuple[str, Optional[Union[tuple[Any, ...], list[Any], dict[str, Any]]]]":
58
+ """Process SQL and parameters for aiosqlite using SQLStatement.
59
+
60
+ aiosqlite supports both named (:name) and positional (?) parameters.
61
+ This method processes the SQL with dialect-aware parsing and handles
62
+ parameters appropriately for aiosqlite.
63
+
64
+ Args:
65
+ sql: SQL statement.
66
+ parameters: Query parameters.
67
+ *filters: Statement filters to apply.
68
+ **kwargs: Additional keyword arguments.
69
+
70
+ Returns:
71
+ Tuple of processed SQL and parameters.
72
+ """
73
+ statement = SQLStatement(sql, parameters, kwargs=kwargs, dialect=self.dialect)
74
+
75
+ # Apply any filters
76
+ for filter_obj in filters:
77
+ statement = statement.apply_filter(filter_obj)
78
+
79
+ processed_sql, processed_params, parsed_expr = statement.process()
80
+ if processed_params is None:
81
+ return processed_sql, None
82
+
83
+ if is_dict(processed_params):
84
+ # For dict parameters, we need to use ordered ? placeholders
85
+ # but only if we have a parsed expression to work with
86
+ if parsed_expr:
87
+ # Collect named parameters in the order they appear in the SQL
88
+ named_params = []
89
+ for node in parsed_expr.find_all(exp.Parameter, exp.Placeholder):
90
+ if isinstance(node, exp.Parameter) and node.name and node.name in processed_params:
91
+ named_params.append(node.name)
92
+ elif (
93
+ isinstance(node, exp.Placeholder)
94
+ and isinstance(node.this, str)
95
+ and node.this in processed_params
96
+ ):
97
+ named_params.append(node.this)
98
+
99
+ if named_params:
100
+ # Transform SQL to use ? placeholders
101
+ def _convert_to_qmark(node: exp.Expression) -> exp.Expression:
102
+ if (isinstance(node, exp.Parameter) and node.name and node.name in processed_params) or (
103
+ isinstance(node, exp.Placeholder)
104
+ and isinstance(node.this, str)
105
+ and node.this in processed_params
106
+ ):
107
+ return exp.Placeholder() # ? placeholder
108
+ return node
109
+
110
+ return parsed_expr.transform(_convert_to_qmark, copy=True).sql(dialect=self.dialect), tuple(
111
+ processed_params[name] for name in named_params
112
+ )
113
+ return processed_sql, processed_params
114
+ if isinstance(processed_params, (list, tuple)):
115
+ return processed_sql, tuple(processed_params)
116
+ return processed_sql, (processed_params,)
117
+
42
118
  # --- Public API Methods --- #
43
119
  @overload
44
120
  async def select(
@@ -46,7 +122,7 @@ class AiosqliteDriver(
46
122
  sql: str,
47
123
  parameters: "Optional[StatementParameterType]" = None,
48
124
  /,
49
- *,
125
+ *filters: "StatementFilter",
50
126
  connection: "Optional[AiosqliteConnection]" = None,
51
127
  schema_type: None = None,
52
128
  **kwargs: Any,
@@ -57,7 +133,7 @@ class AiosqliteDriver(
57
133
  sql: str,
58
134
  parameters: "Optional[StatementParameterType]" = None,
59
135
  /,
60
- *,
136
+ *filters: "StatementFilter",
61
137
  connection: "Optional[AiosqliteConnection]" = None,
62
138
  schema_type: "type[ModelDTOT]",
63
139
  **kwargs: Any,
@@ -65,29 +141,33 @@ class AiosqliteDriver(
65
141
  async def select(
66
142
  self,
67
143
  sql: str,
68
- parameters: Optional["StatementParameterType"] = None,
144
+ parameters: "Optional[StatementParameterType]" = None,
69
145
  /,
70
- *,
71
- connection: Optional["AiosqliteConnection"] = None,
146
+ *filters: "StatementFilter",
147
+ connection: "Optional[AiosqliteConnection]" = None,
72
148
  schema_type: "Optional[type[ModelDTOT]]" = None,
73
149
  **kwargs: Any,
74
- ) -> "Sequence[Union[ModelDTOT, dict[str, Any]]]":
150
+ ) -> "Sequence[Union[dict[str, Any], ModelDTOT]]":
75
151
  """Fetch data from the database.
76
152
 
77
153
  Returns:
78
154
  List of row data as either model instances or dictionaries.
79
155
  """
80
156
  connection = self._connection(connection)
81
- sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
82
- async with self._with_cursor(connection) as cursor:
83
- await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
84
- results = await cursor.fetchall() # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
85
- if not results:
86
- return []
87
- column_names = [c[0] for c in cursor.description or []] # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
88
- if schema_type is None:
89
- return [dict(zip(column_names, row)) for row in results] # pyright: ignore[reportUnknownArgumentType]
90
- return [cast("ModelDTOT", schema_type(**dict(zip(column_names, row)))) for row in results] # pyright: ignore[reportUnknownArgumentType]
157
+ sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
158
+
159
+ # Execute the query
160
+ cursor = await connection.execute(sql, parameters or ())
161
+ results = await cursor.fetchall()
162
+ if not results:
163
+ return []
164
+
165
+ # Get column names
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)
91
171
 
92
172
  @overload
93
173
  async def select_one(
@@ -95,7 +175,7 @@ class AiosqliteDriver(
95
175
  sql: str,
96
176
  parameters: "Optional[StatementParameterType]" = None,
97
177
  /,
98
- *,
178
+ *filters: "StatementFilter",
99
179
  connection: "Optional[AiosqliteConnection]" = None,
100
180
  schema_type: None = None,
101
181
  **kwargs: Any,
@@ -106,7 +186,7 @@ class AiosqliteDriver(
106
186
  sql: str,
107
187
  parameters: "Optional[StatementParameterType]" = None,
108
188
  /,
109
- *,
189
+ *filters: "StatementFilter",
110
190
  connection: "Optional[AiosqliteConnection]" = None,
111
191
  schema_type: "type[ModelDTOT]",
112
192
  **kwargs: Any,
@@ -114,28 +194,32 @@ class AiosqliteDriver(
114
194
  async def select_one(
115
195
  self,
116
196
  sql: str,
117
- parameters: Optional["StatementParameterType"] = None,
197
+ parameters: "Optional[StatementParameterType]" = None,
118
198
  /,
119
- *,
120
- connection: Optional["AiosqliteConnection"] = None,
199
+ *filters: "StatementFilter",
200
+ connection: "Optional[AiosqliteConnection]" = None,
121
201
  schema_type: "Optional[type[ModelDTOT]]" = None,
122
202
  **kwargs: Any,
123
- ) -> "Union[ModelDTOT, dict[str, Any]]":
203
+ ) -> "Union[dict[str, Any], ModelDTOT]":
124
204
  """Fetch one row from the database.
125
205
 
126
206
  Returns:
127
207
  The first row of the query results.
128
208
  """
129
209
  connection = self._connection(connection)
130
- sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
131
- async with self._with_cursor(connection) as cursor:
132
- await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
133
- result = await cursor.fetchone() # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
134
- result = self.check_not_found(result)
135
- column_names = [c[0] for c in cursor.description or []] # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
136
- if schema_type is None:
137
- return dict(zip(column_names, result)) # pyright: ignore[reportUnknownArgumentType, reportUnknownVariableType]
138
- return cast("ModelDTOT", schema_type(**dict(zip(column_names, result)))) # pyright: ignore[reportUnknownArgumentType]
210
+ sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
211
+
212
+ # Execute the query
213
+ cursor = await connection.execute(sql, parameters or ())
214
+ result = await cursor.fetchone()
215
+ result = self.check_not_found(result)
216
+
217
+ # Get column names
218
+ column_names = [column[0] for column in cursor.description]
219
+
220
+ # Convert to dict and then use ResultConverter
221
+ dict_result = dict(zip(column_names, result))
222
+ return self.to_schema(dict_result, schema_type=schema_type)
139
223
 
140
224
  @overload
141
225
  async def select_one_or_none(
@@ -143,7 +227,7 @@ class AiosqliteDriver(
143
227
  sql: str,
144
228
  parameters: "Optional[StatementParameterType]" = None,
145
229
  /,
146
- *,
230
+ *filters: "StatementFilter",
147
231
  connection: "Optional[AiosqliteConnection]" = None,
148
232
  schema_type: None = None,
149
233
  **kwargs: Any,
@@ -154,7 +238,7 @@ class AiosqliteDriver(
154
238
  sql: str,
155
239
  parameters: "Optional[StatementParameterType]" = None,
156
240
  /,
157
- *,
241
+ *filters: "StatementFilter",
158
242
  connection: "Optional[AiosqliteConnection]" = None,
159
243
  schema_type: "type[ModelDTOT]",
160
244
  **kwargs: Any,
@@ -162,29 +246,33 @@ class AiosqliteDriver(
162
246
  async def select_one_or_none(
163
247
  self,
164
248
  sql: str,
165
- parameters: Optional["StatementParameterType"] = None,
249
+ parameters: "Optional[StatementParameterType]" = None,
166
250
  /,
167
- *,
168
- connection: Optional["AiosqliteConnection"] = None,
251
+ *filters: "StatementFilter",
252
+ connection: "Optional[AiosqliteConnection]" = None,
169
253
  schema_type: "Optional[type[ModelDTOT]]" = None,
170
254
  **kwargs: Any,
171
- ) -> "Optional[Union[ModelDTOT, dict[str, Any]]]":
255
+ ) -> "Optional[Union[dict[str, Any], ModelDTOT]]":
172
256
  """Fetch one row from the database.
173
257
 
174
258
  Returns:
175
259
  The first row of the query results.
176
260
  """
177
261
  connection = self._connection(connection)
178
- sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
179
- async with self._with_cursor(connection) as cursor:
180
- await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
181
- result = await cursor.fetchone() # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
182
- if result is None:
183
- return None
184
- column_names = [c[0] for c in cursor.description or []] # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
185
- if schema_type is None:
186
- return dict(zip(column_names, result)) # pyright: ignore[reportUnknownArgumentType, reportUnknownVariableType]
187
- return cast("ModelDTOT", schema_type(**dict(zip(column_names, result)))) # pyright: ignore[reportUnknownArgumentType]
262
+ sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
263
+
264
+ # Execute the query
265
+ cursor = await connection.execute(sql, parameters or ())
266
+ result = await cursor.fetchone()
267
+ if result is None:
268
+ return None
269
+
270
+ # Get column names
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)
188
276
 
189
277
  @overload
190
278
  async def select_value(
@@ -192,7 +280,7 @@ class AiosqliteDriver(
192
280
  sql: str,
193
281
  parameters: "Optional[StatementParameterType]" = None,
194
282
  /,
195
- *,
283
+ *filters: "StatementFilter",
196
284
  connection: "Optional[AiosqliteConnection]" = None,
197
285
  schema_type: None = None,
198
286
  **kwargs: Any,
@@ -203,7 +291,7 @@ class AiosqliteDriver(
203
291
  sql: str,
204
292
  parameters: "Optional[StatementParameterType]" = None,
205
293
  /,
206
- *,
294
+ *filters: "StatementFilter",
207
295
  connection: "Optional[AiosqliteConnection]" = None,
208
296
  schema_type: "type[T]",
209
297
  **kwargs: Any,
@@ -213,7 +301,7 @@ class AiosqliteDriver(
213
301
  sql: str,
214
302
  parameters: "Optional[StatementParameterType]" = None,
215
303
  /,
216
- *,
304
+ *filters: "StatementFilter",
217
305
  connection: "Optional[AiosqliteConnection]" = None,
218
306
  schema_type: "Optional[type[T]]" = None,
219
307
  **kwargs: Any,
@@ -221,17 +309,21 @@ class AiosqliteDriver(
221
309
  """Fetch a single value from the database.
222
310
 
223
311
  Returns:
224
- The first value from the first row of results, or None if no results.
312
+ The first value from the first row of results.
225
313
  """
226
314
  connection = self._connection(connection)
227
- sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
228
- async with self._with_cursor(connection) as cursor:
229
- await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
230
- result = await cursor.fetchone() # pyright: ignore[reportUnknownMemberType]
231
- result = self.check_not_found(result)
232
- if schema_type is None:
233
- return result[0]
234
- return schema_type(result[0]) # type: ignore[call-arg]
315
+ sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
316
+
317
+ # Execute the query
318
+ cursor = await connection.execute(sql, parameters or ())
319
+ result = await cursor.fetchone()
320
+ result = self.check_not_found(result)
321
+
322
+ # Return first value from the row
323
+ result_value = result[0]
324
+ if schema_type is None:
325
+ return result_value
326
+ return schema_type(result_value) # type: ignore[call-arg]
235
327
 
236
328
  @overload
237
329
  async def select_value_or_none(
@@ -239,7 +331,7 @@ class AiosqliteDriver(
239
331
  sql: str,
240
332
  parameters: "Optional[StatementParameterType]" = None,
241
333
  /,
242
- *,
334
+ *filters: "StatementFilter",
243
335
  connection: "Optional[AiosqliteConnection]" = None,
244
336
  schema_type: None = None,
245
337
  **kwargs: Any,
@@ -250,7 +342,7 @@ class AiosqliteDriver(
250
342
  sql: str,
251
343
  parameters: "Optional[StatementParameterType]" = None,
252
344
  /,
253
- *,
345
+ *filters: "StatementFilter",
254
346
  connection: "Optional[AiosqliteConnection]" = None,
255
347
  schema_type: "type[T]",
256
348
  **kwargs: Any,
@@ -260,7 +352,7 @@ class AiosqliteDriver(
260
352
  sql: str,
261
353
  parameters: "Optional[StatementParameterType]" = None,
262
354
  /,
263
- *,
355
+ *filters: "StatementFilter",
264
356
  connection: "Optional[AiosqliteConnection]" = None,
265
357
  schema_type: "Optional[type[T]]" = None,
266
358
  **kwargs: Any,
@@ -271,23 +363,27 @@ class AiosqliteDriver(
271
363
  The first value from the first row of results, or None if no results.
272
364
  """
273
365
  connection = self._connection(connection)
274
- sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
275
- async with self._with_cursor(connection) as cursor:
276
- await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
277
- result = await cursor.fetchone() # pyright: ignore[reportUnknownMemberType]
278
- if result is None:
279
- return None
280
- if schema_type is None:
281
- return result[0]
282
- return schema_type(result[0]) # type: ignore[call-arg]
366
+ sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
367
+
368
+ # Execute the query
369
+ cursor = await connection.execute(sql, parameters or ())
370
+ result = await cursor.fetchone()
371
+ if result is None:
372
+ return None
373
+
374
+ # Return first value from the row
375
+ result_value = result[0]
376
+ if schema_type is None:
377
+ return result_value
378
+ return schema_type(result_value) # type: ignore[call-arg]
283
379
 
284
380
  async def insert_update_delete(
285
381
  self,
286
382
  sql: str,
287
- parameters: Optional["StatementParameterType"] = None,
383
+ parameters: "Optional[StatementParameterType]" = None,
288
384
  /,
289
- *,
290
- connection: Optional["AiosqliteConnection"] = None,
385
+ *filters: "StatementFilter",
386
+ connection: "Optional[AiosqliteConnection]" = None,
291
387
  **kwargs: Any,
292
388
  ) -> int:
293
389
  """Insert, update, or delete data from the database.
@@ -296,11 +392,12 @@ class AiosqliteDriver(
296
392
  Row count affected by the operation.
297
393
  """
298
394
  connection = self._connection(connection)
299
- sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
395
+ sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
300
396
 
301
- async with self._with_cursor(connection) as cursor:
302
- await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
303
- return cursor.rowcount if hasattr(cursor, "rowcount") else -1 # pyright: ignore[reportUnknownVariableType, reportGeneralTypeIssues]
397
+ # Execute the query
398
+ cursor = await connection.execute(sql, parameters or ())
399
+ await connection.commit()
400
+ return cursor.rowcount
304
401
 
305
402
  @overload
306
403
  async def insert_update_delete_returning(
@@ -308,7 +405,7 @@ class AiosqliteDriver(
308
405
  sql: str,
309
406
  parameters: "Optional[StatementParameterType]" = None,
310
407
  /,
311
- *,
408
+ *filters: "StatementFilter",
312
409
  connection: "Optional[AiosqliteConnection]" = None,
313
410
  schema_type: None = None,
314
411
  **kwargs: Any,
@@ -319,7 +416,7 @@ class AiosqliteDriver(
319
416
  sql: str,
320
417
  parameters: "Optional[StatementParameterType]" = None,
321
418
  /,
322
- *,
419
+ *filters: "StatementFilter",
323
420
  connection: "Optional[AiosqliteConnection]" = None,
324
421
  schema_type: "type[ModelDTOT]",
325
422
  **kwargs: Any,
@@ -327,38 +424,42 @@ class AiosqliteDriver(
327
424
  async def insert_update_delete_returning(
328
425
  self,
329
426
  sql: str,
330
- parameters: Optional["StatementParameterType"] = None,
427
+ parameters: "Optional[StatementParameterType]" = None,
331
428
  /,
332
- *,
333
- connection: Optional["AiosqliteConnection"] = None,
429
+ *filters: "StatementFilter",
430
+ connection: "Optional[AiosqliteConnection]" = None,
334
431
  schema_type: "Optional[type[ModelDTOT]]" = None,
335
432
  **kwargs: Any,
336
- ) -> "Optional[Union[dict[str, Any], ModelDTOT]]":
433
+ ) -> "Union[dict[str, Any], ModelDTOT]":
337
434
  """Insert, update, or delete data from the database and return result.
338
435
 
339
436
  Returns:
340
437
  The first row of results.
341
438
  """
342
439
  connection = self._connection(connection)
343
- sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
440
+ sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
441
+
442
+ # Execute the query
443
+ cursor = await connection.execute(sql, parameters or ())
444
+ result = await cursor.fetchone()
445
+ await connection.commit()
446
+ await cursor.close()
344
447
 
345
- async with self._with_cursor(connection) as cursor:
346
- await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
347
- results = list(await cursor.fetchall()) # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
348
- if not results: # Check if empty
349
- return None
350
- column_names = [c[0] for c in cursor.description or []] # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
351
- if schema_type is not None:
352
- return cast("ModelDTOT", schema_type(**dict(zip(column_names, results[0])))) # pyright: ignore[reportUnknownArgumentType, reportUnknownVariableType]
353
- return dict(zip(column_names, results[0])) # pyright: ignore[reportUnknownArgumentType, reportUnknownVariableType]
448
+ result = self.check_not_found(result)
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)
354
456
 
355
457
  async def execute_script(
356
458
  self,
357
459
  sql: str,
358
- parameters: Optional["StatementParameterType"] = None,
460
+ parameters: "Optional[StatementParameterType]" = None,
359
461
  /,
360
- *,
361
- connection: Optional["AiosqliteConnection"] = None,
462
+ connection: "Optional[AiosqliteConnection]" = None,
362
463
  **kwargs: Any,
363
464
  ) -> str:
364
465
  """Execute a script.
@@ -369,34 +470,18 @@ class AiosqliteDriver(
369
470
  connection = self._connection(connection)
370
471
  sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
371
472
 
372
- async with self._with_cursor(connection) as cursor:
373
- await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
374
- return "DONE"
473
+ # Execute the script
474
+ await connection.executescript(sql)
475
+ await connection.commit()
476
+ return "Script executed successfully."
375
477
 
376
- async def execute_script_returning(
377
- self,
378
- sql: str,
379
- parameters: Optional["StatementParameterType"] = None,
380
- /,
381
- *,
382
- connection: Optional["AiosqliteConnection"] = None,
383
- schema_type: "Optional[type[ModelDTOT]]" = None,
384
- **kwargs: Any,
385
- ) -> "Optional[Union[dict[str, Any], ModelDTOT]]":
386
- """Execute a script and return result.
478
+ def _connection(self, connection: "Optional[AiosqliteConnection]" = None) -> "AiosqliteConnection":
479
+ """Get the connection to use for the operation.
480
+
481
+ Args:
482
+ connection: Optional connection to use.
387
483
 
388
484
  Returns:
389
- The first row of results.
485
+ The connection to use.
390
486
  """
391
- connection = self._connection(connection)
392
- sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
393
-
394
- async with self._with_cursor(connection) as cursor:
395
- await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
396
- results = list(await cursor.fetchall()) # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
397
- if not results: # Check if empty
398
- return None
399
- column_names = [c[0] for c in cursor.description or []] # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
400
- if schema_type is not None:
401
- return cast("ModelDTOT", schema_type(**dict(zip(column_names, results[0])))) # pyright: ignore[reportUnknownArgumentType, reportUnknownVariableType]
402
- return dict(zip(column_names, results[0])) # pyright: ignore[reportUnknownArgumentType, reportUnknownVariableType]
487
+ return connection or self.connection