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.
- sqlspec/adapters/adbc/config.py +1 -1
- sqlspec/adapters/adbc/driver.py +336 -165
- sqlspec/adapters/aiosqlite/driver.py +211 -126
- sqlspec/adapters/asyncmy/driver.py +164 -68
- sqlspec/adapters/asyncpg/config.py +3 -1
- sqlspec/adapters/asyncpg/driver.py +190 -231
- sqlspec/adapters/bigquery/driver.py +178 -169
- sqlspec/adapters/duckdb/driver.py +175 -84
- sqlspec/adapters/oracledb/driver.py +224 -90
- sqlspec/adapters/psqlpy/driver.py +267 -187
- sqlspec/adapters/psycopg/driver.py +138 -184
- sqlspec/adapters/sqlite/driver.py +153 -121
- sqlspec/base.py +57 -45
- sqlspec/extensions/litestar/__init__.py +3 -12
- sqlspec/extensions/litestar/config.py +22 -7
- sqlspec/extensions/litestar/handlers.py +142 -85
- sqlspec/extensions/litestar/plugin.py +9 -8
- sqlspec/extensions/litestar/providers.py +521 -0
- sqlspec/filters.py +214 -11
- sqlspec/mixins.py +152 -2
- sqlspec/statement.py +276 -271
- sqlspec/typing.py +18 -1
- sqlspec/utils/__init__.py +2 -2
- sqlspec/utils/singleton.py +35 -0
- sqlspec/utils/sync_tools.py +90 -151
- sqlspec/utils/text.py +68 -5
- {sqlspec-0.10.1.dist-info → sqlspec-0.11.0.dist-info}/METADATA +5 -1
- {sqlspec-0.10.1.dist-info → sqlspec-0.11.0.dist-info}/RECORD +31 -29
- {sqlspec-0.10.1.dist-info → sqlspec-0.11.0.dist-info}/WHEEL +0 -0
- {sqlspec-0.10.1.dist-info → sqlspec-0.11.0.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.10.1.dist-info → sqlspec-0.11.0.dist-info}/licenses/NOTICE +0 -0
|
@@ -1,24 +1,31 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
import sqlite3
|
|
2
3
|
from contextlib import contextmanager
|
|
3
4
|
from sqlite3 import Cursor
|
|
4
|
-
from typing import TYPE_CHECKING, Any, Optional, Union,
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Optional, Union, overload
|
|
5
6
|
|
|
6
7
|
from sqlspec.base import SyncDriverAdapterProtocol
|
|
7
|
-
from sqlspec.mixins import SQLTranslatorMixin
|
|
8
|
+
from sqlspec.mixins import ResultConverter, SQLTranslatorMixin
|
|
9
|
+
from sqlspec.statement import SQLStatement
|
|
10
|
+
from sqlspec.typing import is_dict
|
|
8
11
|
|
|
9
12
|
if TYPE_CHECKING:
|
|
10
13
|
from collections.abc import Generator, Sequence
|
|
11
14
|
|
|
15
|
+
from sqlspec.filters import StatementFilter
|
|
12
16
|
from sqlspec.typing import ModelDTOT, StatementParameterType, T
|
|
13
17
|
|
|
14
18
|
__all__ = ("SqliteConnection", "SqliteDriver")
|
|
15
19
|
|
|
20
|
+
logger = logging.getLogger("sqlspec")
|
|
21
|
+
|
|
16
22
|
SqliteConnection = sqlite3.Connection
|
|
17
23
|
|
|
18
24
|
|
|
19
25
|
class SqliteDriver(
|
|
20
26
|
SQLTranslatorMixin["SqliteConnection"],
|
|
21
27
|
SyncDriverAdapterProtocol["SqliteConnection"],
|
|
28
|
+
ResultConverter,
|
|
22
29
|
):
|
|
23
30
|
"""SQLite Sync Driver Adapter."""
|
|
24
31
|
|
|
@@ -40,6 +47,48 @@ class SqliteDriver(
|
|
|
40
47
|
finally:
|
|
41
48
|
cursor.close()
|
|
42
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 SQLite using SQLStatement.
|
|
59
|
+
|
|
60
|
+
SQLite supports both named (:name) and positional (?) parameters.
|
|
61
|
+
This method processes the SQL with dialect-aware parsing and handles
|
|
62
|
+
parameters appropriately for SQLite.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
sql: The SQL to process.
|
|
66
|
+
parameters: The parameters to process.
|
|
67
|
+
*filters: Statement filters to apply.
|
|
68
|
+
**kwargs: Additional keyword arguments.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
A tuple of (processed SQL, processed parameters).
|
|
72
|
+
"""
|
|
73
|
+
# Create a SQLStatement with SQLite dialect
|
|
74
|
+
statement = SQLStatement(sql, parameters, kwargs=kwargs, dialect=self.dialect)
|
|
75
|
+
|
|
76
|
+
for filter_obj in filters:
|
|
77
|
+
statement = statement.apply_filter(filter_obj)
|
|
78
|
+
|
|
79
|
+
processed_sql, processed_params, _ = statement.process()
|
|
80
|
+
|
|
81
|
+
if processed_params is None:
|
|
82
|
+
return processed_sql, None
|
|
83
|
+
|
|
84
|
+
if is_dict(processed_params):
|
|
85
|
+
return processed_sql, processed_params
|
|
86
|
+
|
|
87
|
+
if isinstance(processed_params, (list, tuple)):
|
|
88
|
+
return processed_sql, tuple(processed_params)
|
|
89
|
+
|
|
90
|
+
return processed_sql, (processed_params,)
|
|
91
|
+
|
|
43
92
|
# --- Public API Methods --- #
|
|
44
93
|
@overload
|
|
45
94
|
def select(
|
|
@@ -47,7 +96,7 @@ class SqliteDriver(
|
|
|
47
96
|
sql: str,
|
|
48
97
|
parameters: "Optional[StatementParameterType]" = None,
|
|
49
98
|
/,
|
|
50
|
-
|
|
99
|
+
*filters: "StatementFilter",
|
|
51
100
|
connection: "Optional[SqliteConnection]" = None,
|
|
52
101
|
schema_type: None = None,
|
|
53
102
|
**kwargs: Any,
|
|
@@ -58,7 +107,7 @@ class SqliteDriver(
|
|
|
58
107
|
sql: str,
|
|
59
108
|
parameters: "Optional[StatementParameterType]" = None,
|
|
60
109
|
/,
|
|
61
|
-
|
|
110
|
+
*filters: "StatementFilter",
|
|
62
111
|
connection: "Optional[SqliteConnection]" = None,
|
|
63
112
|
schema_type: "type[ModelDTOT]",
|
|
64
113
|
**kwargs: Any,
|
|
@@ -66,32 +115,31 @@ class SqliteDriver(
|
|
|
66
115
|
def select(
|
|
67
116
|
self,
|
|
68
117
|
sql: str,
|
|
69
|
-
parameters: Optional[
|
|
118
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
70
119
|
/,
|
|
71
|
-
|
|
72
|
-
connection: Optional[
|
|
120
|
+
*filters: "StatementFilter",
|
|
121
|
+
connection: "Optional[SqliteConnection]" = None,
|
|
73
122
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
74
123
|
**kwargs: Any,
|
|
75
|
-
) -> "Sequence[Union[
|
|
124
|
+
) -> "Sequence[Union[dict[str, Any], ModelDTOT]]":
|
|
76
125
|
"""Fetch data from the database.
|
|
77
126
|
|
|
78
127
|
Returns:
|
|
79
128
|
List of row data as either model instances or dictionaries.
|
|
80
129
|
"""
|
|
81
130
|
connection = self._connection(connection)
|
|
82
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
131
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
132
|
+
|
|
83
133
|
with self._with_cursor(connection) as cursor:
|
|
84
|
-
|
|
85
|
-
cursor.execute(sql) # pyright: ignore[reportUnknownMemberType]
|
|
86
|
-
else:
|
|
87
|
-
cursor.execute(sql, parameters)
|
|
134
|
+
cursor.execute(sql, parameters or [])
|
|
88
135
|
results = cursor.fetchall()
|
|
89
136
|
if not results:
|
|
90
137
|
return []
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
138
|
+
|
|
139
|
+
# Get column names
|
|
140
|
+
column_names = [column[0] for column in cursor.description]
|
|
141
|
+
|
|
142
|
+
return self.to_schema([dict(zip(column_names, row)) for row in results], schema_type=schema_type)
|
|
95
143
|
|
|
96
144
|
@overload
|
|
97
145
|
def select_one(
|
|
@@ -99,7 +147,7 @@ class SqliteDriver(
|
|
|
99
147
|
sql: str,
|
|
100
148
|
parameters: "Optional[StatementParameterType]" = None,
|
|
101
149
|
/,
|
|
102
|
-
|
|
150
|
+
*filters: "StatementFilter",
|
|
103
151
|
connection: "Optional[SqliteConnection]" = None,
|
|
104
152
|
schema_type: None = None,
|
|
105
153
|
**kwargs: Any,
|
|
@@ -110,7 +158,7 @@ class SqliteDriver(
|
|
|
110
158
|
sql: str,
|
|
111
159
|
parameters: "Optional[StatementParameterType]" = None,
|
|
112
160
|
/,
|
|
113
|
-
|
|
161
|
+
*filters: "StatementFilter",
|
|
114
162
|
connection: "Optional[SqliteConnection]" = None,
|
|
115
163
|
schema_type: "type[ModelDTOT]",
|
|
116
164
|
**kwargs: Any,
|
|
@@ -118,31 +166,31 @@ class SqliteDriver(
|
|
|
118
166
|
def select_one(
|
|
119
167
|
self,
|
|
120
168
|
sql: str,
|
|
121
|
-
parameters: Optional[
|
|
169
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
122
170
|
/,
|
|
123
|
-
|
|
124
|
-
connection: Optional[
|
|
171
|
+
*filters: "StatementFilter",
|
|
172
|
+
connection: "Optional[SqliteConnection]" = None,
|
|
125
173
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
126
174
|
**kwargs: Any,
|
|
127
|
-
) -> "Union[
|
|
175
|
+
) -> "Union[dict[str, Any], ModelDTOT]":
|
|
128
176
|
"""Fetch one row from the database.
|
|
129
177
|
|
|
130
178
|
Returns:
|
|
131
179
|
The first row of the query results.
|
|
132
180
|
"""
|
|
133
181
|
connection = self._connection(connection)
|
|
134
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
182
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
183
|
+
|
|
184
|
+
# Execute the query
|
|
185
|
+
cursor = connection.cursor()
|
|
186
|
+
cursor.execute(sql, parameters or [])
|
|
187
|
+
result = cursor.fetchone()
|
|
188
|
+
result = self.check_not_found(result)
|
|
189
|
+
|
|
190
|
+
# Get column names
|
|
191
|
+
column_names = [column[0] for column in cursor.description]
|
|
192
|
+
|
|
193
|
+
return self.to_schema(dict(zip(column_names, result)), schema_type=schema_type)
|
|
146
194
|
|
|
147
195
|
@overload
|
|
148
196
|
def select_one_or_none(
|
|
@@ -150,7 +198,7 @@ class SqliteDriver(
|
|
|
150
198
|
sql: str,
|
|
151
199
|
parameters: "Optional[StatementParameterType]" = None,
|
|
152
200
|
/,
|
|
153
|
-
|
|
201
|
+
*filters: "StatementFilter",
|
|
154
202
|
connection: "Optional[SqliteConnection]" = None,
|
|
155
203
|
schema_type: None = None,
|
|
156
204
|
**kwargs: Any,
|
|
@@ -161,7 +209,7 @@ class SqliteDriver(
|
|
|
161
209
|
sql: str,
|
|
162
210
|
parameters: "Optional[StatementParameterType]" = None,
|
|
163
211
|
/,
|
|
164
|
-
|
|
212
|
+
*filters: "StatementFilter",
|
|
165
213
|
connection: "Optional[SqliteConnection]" = None,
|
|
166
214
|
schema_type: "type[ModelDTOT]",
|
|
167
215
|
**kwargs: Any,
|
|
@@ -169,32 +217,31 @@ class SqliteDriver(
|
|
|
169
217
|
def select_one_or_none(
|
|
170
218
|
self,
|
|
171
219
|
sql: str,
|
|
172
|
-
parameters: Optional[
|
|
220
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
173
221
|
/,
|
|
174
|
-
|
|
175
|
-
connection: Optional[
|
|
222
|
+
*filters: "StatementFilter",
|
|
223
|
+
connection: "Optional[SqliteConnection]" = None,
|
|
176
224
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
177
225
|
**kwargs: Any,
|
|
178
|
-
) -> "Optional[Union[
|
|
226
|
+
) -> "Optional[Union[dict[str, Any], ModelDTOT]]":
|
|
179
227
|
"""Fetch one row from the database.
|
|
180
228
|
|
|
181
229
|
Returns:
|
|
182
|
-
The first row of the query results.
|
|
230
|
+
The first row of the query results, or None if no results.
|
|
183
231
|
"""
|
|
184
232
|
connection = self._connection(connection)
|
|
185
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
233
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
234
|
+
|
|
186
235
|
with self._with_cursor(connection) as cursor:
|
|
187
|
-
|
|
188
|
-
cursor.execute(sql) # pyright: ignore[reportUnknownMemberType]
|
|
189
|
-
else:
|
|
190
|
-
cursor.execute(sql, parameters)
|
|
236
|
+
cursor.execute(sql, parameters or [])
|
|
191
237
|
result = cursor.fetchone()
|
|
192
238
|
if result is None:
|
|
193
239
|
return None
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
240
|
+
|
|
241
|
+
# Get column names
|
|
242
|
+
column_names = [column[0] for column in cursor.description]
|
|
243
|
+
|
|
244
|
+
return self.to_schema(dict(zip(column_names, result)), schema_type=schema_type)
|
|
198
245
|
|
|
199
246
|
@overload
|
|
200
247
|
def select_value(
|
|
@@ -202,7 +249,7 @@ class SqliteDriver(
|
|
|
202
249
|
sql: str,
|
|
203
250
|
parameters: "Optional[StatementParameterType]" = None,
|
|
204
251
|
/,
|
|
205
|
-
|
|
252
|
+
*filters: "StatementFilter",
|
|
206
253
|
connection: "Optional[SqliteConnection]" = None,
|
|
207
254
|
schema_type: None = None,
|
|
208
255
|
**kwargs: Any,
|
|
@@ -213,7 +260,7 @@ class SqliteDriver(
|
|
|
213
260
|
sql: str,
|
|
214
261
|
parameters: "Optional[StatementParameterType]" = None,
|
|
215
262
|
/,
|
|
216
|
-
|
|
263
|
+
*filters: "StatementFilter",
|
|
217
264
|
connection: "Optional[SqliteConnection]" = None,
|
|
218
265
|
schema_type: "type[T]",
|
|
219
266
|
**kwargs: Any,
|
|
@@ -223,7 +270,7 @@ class SqliteDriver(
|
|
|
223
270
|
sql: str,
|
|
224
271
|
parameters: "Optional[StatementParameterType]" = None,
|
|
225
272
|
/,
|
|
226
|
-
|
|
273
|
+
*filters: "StatementFilter",
|
|
227
274
|
connection: "Optional[SqliteConnection]" = None,
|
|
228
275
|
schema_type: "Optional[type[T]]" = None,
|
|
229
276
|
**kwargs: Any,
|
|
@@ -231,20 +278,21 @@ class SqliteDriver(
|
|
|
231
278
|
"""Fetch a single value from the database.
|
|
232
279
|
|
|
233
280
|
Returns:
|
|
234
|
-
The first value from the first row of results
|
|
281
|
+
The first value from the first row of results.
|
|
235
282
|
"""
|
|
236
283
|
connection = self._connection(connection)
|
|
237
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
284
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
285
|
+
|
|
238
286
|
with self._with_cursor(connection) as cursor:
|
|
239
|
-
|
|
240
|
-
cursor.execute(sql) # pyright: ignore[reportUnknownMemberType]
|
|
241
|
-
else:
|
|
242
|
-
cursor.execute(sql, parameters)
|
|
287
|
+
cursor.execute(sql, parameters or [])
|
|
243
288
|
result = cursor.fetchone()
|
|
244
289
|
result = self.check_not_found(result)
|
|
290
|
+
|
|
291
|
+
# Return first value from the row
|
|
292
|
+
result_value = result[0]
|
|
245
293
|
if schema_type is None:
|
|
246
|
-
return
|
|
247
|
-
return schema_type(
|
|
294
|
+
return result_value
|
|
295
|
+
return schema_type(result_value) # type: ignore[call-arg]
|
|
248
296
|
|
|
249
297
|
@overload
|
|
250
298
|
def select_value_or_none(
|
|
@@ -252,7 +300,7 @@ class SqliteDriver(
|
|
|
252
300
|
sql: str,
|
|
253
301
|
parameters: "Optional[StatementParameterType]" = None,
|
|
254
302
|
/,
|
|
255
|
-
|
|
303
|
+
*filters: "StatementFilter",
|
|
256
304
|
connection: "Optional[SqliteConnection]" = None,
|
|
257
305
|
schema_type: None = None,
|
|
258
306
|
**kwargs: Any,
|
|
@@ -263,7 +311,7 @@ class SqliteDriver(
|
|
|
263
311
|
sql: str,
|
|
264
312
|
parameters: "Optional[StatementParameterType]" = None,
|
|
265
313
|
/,
|
|
266
|
-
|
|
314
|
+
*filters: "StatementFilter",
|
|
267
315
|
connection: "Optional[SqliteConnection]" = None,
|
|
268
316
|
schema_type: "type[T]",
|
|
269
317
|
**kwargs: Any,
|
|
@@ -273,7 +321,7 @@ class SqliteDriver(
|
|
|
273
321
|
sql: str,
|
|
274
322
|
parameters: "Optional[StatementParameterType]" = None,
|
|
275
323
|
/,
|
|
276
|
-
|
|
324
|
+
*filters: "StatementFilter",
|
|
277
325
|
connection: "Optional[SqliteConnection]" = None,
|
|
278
326
|
schema_type: "Optional[type[T]]" = None,
|
|
279
327
|
**kwargs: Any,
|
|
@@ -284,26 +332,27 @@ class SqliteDriver(
|
|
|
284
332
|
The first value from the first row of results, or None if no results.
|
|
285
333
|
"""
|
|
286
334
|
connection = self._connection(connection)
|
|
287
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
335
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
336
|
+
|
|
288
337
|
with self._with_cursor(connection) as cursor:
|
|
289
|
-
|
|
290
|
-
cursor.execute(sql) # pyright: ignore[reportUnknownMemberType]
|
|
291
|
-
else:
|
|
292
|
-
cursor.execute(sql, parameters)
|
|
338
|
+
cursor.execute(sql, parameters or [])
|
|
293
339
|
result = cursor.fetchone()
|
|
294
340
|
if result is None:
|
|
295
341
|
return None
|
|
342
|
+
|
|
343
|
+
# Return first value from the row
|
|
344
|
+
result_value = result[0]
|
|
296
345
|
if schema_type is None:
|
|
297
|
-
return
|
|
298
|
-
return schema_type(
|
|
346
|
+
return result_value
|
|
347
|
+
return schema_type(result_value) # type: ignore[call-arg]
|
|
299
348
|
|
|
300
349
|
def insert_update_delete(
|
|
301
350
|
self,
|
|
302
351
|
sql: str,
|
|
303
|
-
parameters: Optional[
|
|
352
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
304
353
|
/,
|
|
305
|
-
|
|
306
|
-
connection: Optional[
|
|
354
|
+
*filters: "StatementFilter",
|
|
355
|
+
connection: "Optional[SqliteConnection]" = None,
|
|
307
356
|
**kwargs: Any,
|
|
308
357
|
) -> int:
|
|
309
358
|
"""Insert, update, or delete data from the database.
|
|
@@ -312,14 +361,11 @@ class SqliteDriver(
|
|
|
312
361
|
Row count affected by the operation.
|
|
313
362
|
"""
|
|
314
363
|
connection = self._connection(connection)
|
|
315
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
364
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
316
365
|
|
|
317
366
|
with self._with_cursor(connection) as cursor:
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
else:
|
|
321
|
-
cursor.execute(sql, parameters)
|
|
322
|
-
return cursor.rowcount if hasattr(cursor, "rowcount") else -1
|
|
367
|
+
cursor.execute(sql, parameters or [])
|
|
368
|
+
return cursor.rowcount
|
|
323
369
|
|
|
324
370
|
@overload
|
|
325
371
|
def insert_update_delete_returning(
|
|
@@ -327,7 +373,7 @@ class SqliteDriver(
|
|
|
327
373
|
sql: str,
|
|
328
374
|
parameters: "Optional[StatementParameterType]" = None,
|
|
329
375
|
/,
|
|
330
|
-
|
|
376
|
+
*filters: "StatementFilter",
|
|
331
377
|
connection: "Optional[SqliteConnection]" = None,
|
|
332
378
|
schema_type: None = None,
|
|
333
379
|
**kwargs: Any,
|
|
@@ -338,7 +384,7 @@ class SqliteDriver(
|
|
|
338
384
|
sql: str,
|
|
339
385
|
parameters: "Optional[StatementParameterType]" = None,
|
|
340
386
|
/,
|
|
341
|
-
|
|
387
|
+
*filters: "StatementFilter",
|
|
342
388
|
connection: "Optional[SqliteConnection]" = None,
|
|
343
389
|
schema_type: "type[ModelDTOT]",
|
|
344
390
|
**kwargs: Any,
|
|
@@ -346,54 +392,34 @@ class SqliteDriver(
|
|
|
346
392
|
def insert_update_delete_returning(
|
|
347
393
|
self,
|
|
348
394
|
sql: str,
|
|
349
|
-
parameters: Optional[
|
|
395
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
350
396
|
/,
|
|
351
|
-
|
|
352
|
-
connection: Optional[
|
|
397
|
+
*filters: "StatementFilter",
|
|
398
|
+
connection: "Optional[SqliteConnection]" = None,
|
|
353
399
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
354
400
|
**kwargs: Any,
|
|
355
|
-
) -> "
|
|
401
|
+
) -> "Union[dict[str, Any], ModelDTOT]":
|
|
356
402
|
"""Insert, update, or delete data from the database and return result.
|
|
357
403
|
|
|
358
404
|
Returns:
|
|
359
405
|
The first row of results.
|
|
360
406
|
"""
|
|
361
407
|
connection = self._connection(connection)
|
|
362
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
408
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
363
409
|
|
|
364
410
|
with self._with_cursor(connection) as cursor:
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
if len(result) == 0:
|
|
371
|
-
return None
|
|
372
|
-
|
|
373
|
-
# Get column names from cursor description
|
|
374
|
-
column_names = [c[0] for c in cursor.description or []]
|
|
375
|
-
|
|
376
|
-
# Get the first row's values - ensure we're getting the actual values
|
|
377
|
-
row_values = result[0]
|
|
378
|
-
|
|
379
|
-
# Debug print to see what we're getting
|
|
380
|
-
|
|
381
|
-
# Create dictionary mapping column names to values
|
|
382
|
-
result_dict = {}
|
|
383
|
-
for i, col_name in enumerate(column_names):
|
|
384
|
-
result_dict[col_name] = row_values[i]
|
|
385
|
-
|
|
386
|
-
if schema_type is not None:
|
|
387
|
-
return cast("ModelDTOT", schema_type(**result_dict))
|
|
388
|
-
return result_dict
|
|
411
|
+
cursor.execute(sql, parameters or [])
|
|
412
|
+
result = cursor.fetchone()
|
|
413
|
+
result = self.check_not_found(result)
|
|
414
|
+
column_names = [column[0] for column in cursor.description]
|
|
415
|
+
return self.to_schema(dict(zip(column_names, result)), schema_type=schema_type)
|
|
389
416
|
|
|
390
417
|
def execute_script(
|
|
391
418
|
self,
|
|
392
419
|
sql: str,
|
|
393
|
-
parameters: Optional[
|
|
420
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
394
421
|
/,
|
|
395
|
-
|
|
396
|
-
connection: Optional["SqliteConnection"] = None,
|
|
422
|
+
connection: "Optional[SqliteConnection]" = None,
|
|
397
423
|
**kwargs: Any,
|
|
398
424
|
) -> str:
|
|
399
425
|
"""Execute a script.
|
|
@@ -404,11 +430,17 @@ class SqliteDriver(
|
|
|
404
430
|
connection = self._connection(connection)
|
|
405
431
|
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
406
432
|
|
|
407
|
-
# The _process_sql_params handles parameter formatting for the dialect.
|
|
408
433
|
with self._with_cursor(connection) as cursor:
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
else:
|
|
412
|
-
cursor.execute(sql, parameters)
|
|
434
|
+
cursor.executescript(sql)
|
|
435
|
+
return "DONE"
|
|
413
436
|
|
|
414
|
-
|
|
437
|
+
def _connection(self, connection: "Optional[SqliteConnection]" = None) -> "SqliteConnection":
|
|
438
|
+
"""Get the connection to use for the operation.
|
|
439
|
+
|
|
440
|
+
Args:
|
|
441
|
+
connection: Optional connection to use.
|
|
442
|
+
|
|
443
|
+
Returns:
|
|
444
|
+
The connection to use.
|
|
445
|
+
"""
|
|
446
|
+
return connection or self.connection
|