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