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,4 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
import re
|
|
2
3
|
from contextlib import asynccontextmanager, contextmanager
|
|
3
4
|
from typing import TYPE_CHECKING, Any, Optional, Union, cast, overload
|
|
4
5
|
|
|
@@ -6,12 +7,14 @@ from psycopg import AsyncConnection, Connection
|
|
|
6
7
|
from psycopg.rows import dict_row
|
|
7
8
|
|
|
8
9
|
from sqlspec.base import AsyncDriverAdapterProtocol, SyncDriverAdapterProtocol
|
|
9
|
-
from sqlspec.exceptions import
|
|
10
|
-
from sqlspec.
|
|
11
|
-
from sqlspec.
|
|
10
|
+
from sqlspec.exceptions import ParameterStyleMismatchError
|
|
11
|
+
from sqlspec.filters import StatementFilter
|
|
12
|
+
from sqlspec.mixins import ResultConverter, SQLTranslatorMixin
|
|
13
|
+
from sqlspec.statement import SQLStatement
|
|
14
|
+
from sqlspec.typing import is_dict
|
|
12
15
|
|
|
13
16
|
if TYPE_CHECKING:
|
|
14
|
-
from collections.abc import AsyncGenerator, Generator, Sequence
|
|
17
|
+
from collections.abc import AsyncGenerator, Generator, Mapping, Sequence
|
|
15
18
|
|
|
16
19
|
from sqlspec.typing import ModelDTOT, StatementParameterType, T
|
|
17
20
|
|
|
@@ -19,130 +22,96 @@ logger = logging.getLogger("sqlspec")
|
|
|
19
22
|
|
|
20
23
|
__all__ = ("PsycopgAsyncConnection", "PsycopgAsyncDriver", "PsycopgSyncConnection", "PsycopgSyncDriver")
|
|
21
24
|
|
|
25
|
+
|
|
26
|
+
NAMED_PARAMS_PATTERN = re.compile(r"(?<!:):([a-zA-Z0-9_]+)")
|
|
27
|
+
# Pattern matches %(name)s format while trying to avoid matches in string literals and comments
|
|
28
|
+
PSYCOPG_PARAMS_PATTERN = re.compile(r"(?<!'|\"|\w)%\(([a-zA-Z0-9_]+)\)s(?!'|\")")
|
|
29
|
+
|
|
22
30
|
PsycopgSyncConnection = Connection
|
|
23
31
|
PsycopgAsyncConnection = AsyncConnection
|
|
24
32
|
|
|
25
33
|
|
|
26
34
|
class PsycopgDriverBase:
|
|
27
|
-
dialect: str
|
|
35
|
+
dialect: str = "postgres"
|
|
28
36
|
|
|
29
37
|
def _process_sql_params(
|
|
30
38
|
self,
|
|
31
39
|
sql: str,
|
|
32
40
|
parameters: "Optional[StatementParameterType]" = None,
|
|
33
|
-
|
|
41
|
+
*filters: "StatementFilter",
|
|
34
42
|
**kwargs: Any,
|
|
35
43
|
) -> "tuple[str, Optional[Union[tuple[Any, ...], list[Any], dict[str, Any]]]]":
|
|
36
|
-
"""Process SQL and parameters
|
|
37
|
-
|
|
38
|
-
|
|
44
|
+
"""Process SQL and parameters using SQLStatement with dialect support.
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
sql: The SQL statement to process.
|
|
48
|
+
parameters: The parameters to bind to the statement.
|
|
49
|
+
*filters: Statement filters to apply.
|
|
50
|
+
**kwargs: Additional keyword arguments.
|
|
51
|
+
|
|
52
|
+
Raises:
|
|
53
|
+
ParameterStyleMismatchError: If the parameter style is mismatched.
|
|
54
|
+
|
|
55
|
+
Returns:
|
|
56
|
+
A tuple of (sql, parameters) ready for execution.
|
|
57
|
+
"""
|
|
58
|
+
data_params_for_statement: Optional[Union[Mapping[str, Any], Sequence[Any]]] = None
|
|
59
|
+
combined_filters_list: list[StatementFilter] = list(filters)
|
|
60
|
+
|
|
61
|
+
if parameters is not None:
|
|
62
|
+
if isinstance(parameters, StatementFilter):
|
|
63
|
+
combined_filters_list.insert(0, parameters)
|
|
64
|
+
else:
|
|
65
|
+
data_params_for_statement = parameters
|
|
66
|
+
if data_params_for_statement is not None and not isinstance(data_params_for_statement, (list, tuple, dict)):
|
|
67
|
+
data_params_for_statement = (data_params_for_statement,)
|
|
68
|
+
statement = SQLStatement(sql, data_params_for_statement, kwargs=kwargs, dialect=self.dialect)
|
|
39
69
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
last_end = 0
|
|
44
|
-
found_params_regex: list[str] = []
|
|
70
|
+
# Apply all statement filters
|
|
71
|
+
for filter_obj in combined_filters_list:
|
|
72
|
+
statement = statement.apply_filter(filter_obj)
|
|
45
73
|
|
|
46
|
-
|
|
47
|
-
if match.group("dquote") or match.group("squote") or match.group("comment"):
|
|
48
|
-
continue
|
|
74
|
+
processed_sql, processed_params, _ = statement.process()
|
|
49
75
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
found_params_regex.append(var_name)
|
|
53
|
-
start = match.start("var_name") - 1
|
|
54
|
-
end = match.end("var_name")
|
|
76
|
+
if is_dict(processed_params):
|
|
77
|
+
named_params = NAMED_PARAMS_PATTERN.findall(processed_sql)
|
|
55
78
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
f"Processed SQL: {processed_sql}"
|
|
60
|
-
)
|
|
61
|
-
raise SQLParsingError(msg)
|
|
79
|
+
if not named_params:
|
|
80
|
+
if PSYCOPG_PARAMS_PATTERN.search(processed_sql):
|
|
81
|
+
return processed_sql, processed_params
|
|
62
82
|
|
|
63
|
-
|
|
64
|
-
|
|
83
|
+
if processed_params:
|
|
84
|
+
msg = "psycopg: Dictionary parameters provided, but no named placeholders found in SQL."
|
|
85
|
+
raise ParameterStyleMismatchError(msg)
|
|
86
|
+
return processed_sql, None
|
|
65
87
|
|
|
66
|
-
|
|
67
|
-
|
|
88
|
+
# Convert named parameters to psycopg's preferred format
|
|
89
|
+
return NAMED_PARAMS_PATTERN.sub("%s", processed_sql), tuple(processed_params[name] for name in named_params)
|
|
68
90
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
list(parameter_dict.keys()),
|
|
73
|
-
processed_sql,
|
|
74
|
-
)
|
|
75
|
-
return processed_sql, parameter_dict
|
|
91
|
+
# For sequence parameters, ensure they're a tuple
|
|
92
|
+
if isinstance(processed_params, (list, tuple)):
|
|
93
|
+
return processed_sql, tuple(processed_params)
|
|
76
94
|
|
|
77
|
-
|
|
95
|
+
# For scalar parameter or None
|
|
96
|
+
if processed_params is not None:
|
|
97
|
+
return processed_sql, (processed_params,)
|
|
78
98
|
|
|
79
|
-
return processed_sql,
|
|
99
|
+
return processed_sql, None
|
|
80
100
|
|
|
81
101
|
|
|
82
102
|
class PsycopgSyncDriver(
|
|
83
103
|
PsycopgDriverBase,
|
|
84
104
|
SQLTranslatorMixin["PsycopgSyncConnection"],
|
|
85
105
|
SyncDriverAdapterProtocol["PsycopgSyncConnection"],
|
|
106
|
+
ResultConverter,
|
|
86
107
|
):
|
|
87
108
|
"""Psycopg Sync Driver Adapter."""
|
|
88
109
|
|
|
89
110
|
connection: "PsycopgSyncConnection"
|
|
90
|
-
dialect: str = "postgres"
|
|
91
111
|
|
|
92
112
|
def __init__(self, connection: "PsycopgSyncConnection") -> None:
|
|
93
113
|
self.connection = connection
|
|
94
114
|
|
|
95
|
-
def _process_sql_params(
|
|
96
|
-
self,
|
|
97
|
-
sql: str,
|
|
98
|
-
parameters: "Optional[StatementParameterType]" = None,
|
|
99
|
-
/,
|
|
100
|
-
**kwargs: Any,
|
|
101
|
-
) -> "tuple[str, Optional[Union[tuple[Any, ...], list[Any], dict[str, Any]]]]":
|
|
102
|
-
stmt = SQLStatement(sql=sql, parameters=parameters, dialect=self.dialect, kwargs=kwargs or None)
|
|
103
|
-
processed_sql, processed_params = stmt.process()
|
|
104
|
-
|
|
105
|
-
if isinstance(processed_params, dict):
|
|
106
|
-
parameter_dict = processed_params
|
|
107
|
-
processed_sql_parts: list[str] = []
|
|
108
|
-
last_end = 0
|
|
109
|
-
found_params_regex: list[str] = []
|
|
110
|
-
|
|
111
|
-
for match in PARAM_REGEX.finditer(processed_sql):
|
|
112
|
-
if match.group("dquote") or match.group("squote") or match.group("comment"):
|
|
113
|
-
continue
|
|
114
|
-
|
|
115
|
-
if match.group("var_name"):
|
|
116
|
-
var_name = match.group("var_name")
|
|
117
|
-
found_params_regex.append(var_name)
|
|
118
|
-
start = match.start("var_name") - 1
|
|
119
|
-
end = match.end("var_name")
|
|
120
|
-
|
|
121
|
-
if var_name not in parameter_dict:
|
|
122
|
-
msg = (
|
|
123
|
-
f"Named parameter ':{var_name}' found in SQL but missing from processed parameters. "
|
|
124
|
-
f"Processed SQL: {processed_sql}"
|
|
125
|
-
)
|
|
126
|
-
raise SQLParsingError(msg)
|
|
127
|
-
|
|
128
|
-
processed_sql_parts.extend((processed_sql[last_end:start], f"%({var_name})s"))
|
|
129
|
-
last_end = end
|
|
130
|
-
|
|
131
|
-
processed_sql_parts.append(processed_sql[last_end:])
|
|
132
|
-
final_sql = "".join(processed_sql_parts)
|
|
133
|
-
|
|
134
|
-
if not found_params_regex and parameter_dict:
|
|
135
|
-
logger.warning(
|
|
136
|
-
"Dict params provided (%s), but no :name placeholders found. SQL: %s",
|
|
137
|
-
list(parameter_dict.keys()),
|
|
138
|
-
processed_sql,
|
|
139
|
-
)
|
|
140
|
-
return processed_sql, parameter_dict
|
|
141
|
-
|
|
142
|
-
return final_sql, parameter_dict
|
|
143
|
-
|
|
144
|
-
return processed_sql, processed_params
|
|
145
|
-
|
|
146
115
|
@staticmethod
|
|
147
116
|
@contextmanager
|
|
148
117
|
def _with_cursor(connection: "PsycopgSyncConnection") -> "Generator[Any, None, None]":
|
|
@@ -158,8 +127,7 @@ class PsycopgSyncDriver(
|
|
|
158
127
|
self,
|
|
159
128
|
sql: str,
|
|
160
129
|
parameters: "Optional[StatementParameterType]" = None,
|
|
161
|
-
|
|
162
|
-
*,
|
|
130
|
+
*filters: "StatementFilter",
|
|
163
131
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
164
132
|
schema_type: None = None,
|
|
165
133
|
**kwargs: Any,
|
|
@@ -169,8 +137,7 @@ class PsycopgSyncDriver(
|
|
|
169
137
|
self,
|
|
170
138
|
sql: str,
|
|
171
139
|
parameters: "Optional[StatementParameterType]" = None,
|
|
172
|
-
|
|
173
|
-
*,
|
|
140
|
+
*filters: "StatementFilter",
|
|
174
141
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
175
142
|
schema_type: "type[ModelDTOT]",
|
|
176
143
|
**kwargs: Any,
|
|
@@ -179,8 +146,7 @@ class PsycopgSyncDriver(
|
|
|
179
146
|
self,
|
|
180
147
|
sql: str,
|
|
181
148
|
parameters: "Optional[StatementParameterType]" = None,
|
|
182
|
-
|
|
183
|
-
*,
|
|
149
|
+
*filters: "StatementFilter",
|
|
184
150
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
185
151
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
186
152
|
**kwargs: Any,
|
|
@@ -191,24 +157,21 @@ class PsycopgSyncDriver(
|
|
|
191
157
|
List of row data as either model instances or dictionaries.
|
|
192
158
|
"""
|
|
193
159
|
connection = self._connection(connection)
|
|
194
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
160
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
195
161
|
with self._with_cursor(connection) as cursor:
|
|
196
162
|
cursor.execute(sql, parameters)
|
|
197
163
|
results = cursor.fetchall()
|
|
198
164
|
if not results:
|
|
199
165
|
return []
|
|
200
166
|
|
|
201
|
-
|
|
202
|
-
return [cast("ModelDTOT", schema_type(**row)) for row in results] # pyright: ignore[reportUnknownArgumentType]
|
|
203
|
-
return [cast("dict[str,Any]", row) for row in results] # pyright: ignore[reportUnknownArgumentType]
|
|
167
|
+
return self.to_schema(cast("Sequence[dict[str, Any]]", results), schema_type=schema_type)
|
|
204
168
|
|
|
205
169
|
@overload
|
|
206
170
|
def select_one(
|
|
207
171
|
self,
|
|
208
172
|
sql: str,
|
|
209
173
|
parameters: "Optional[StatementParameterType]" = None,
|
|
210
|
-
|
|
211
|
-
*,
|
|
174
|
+
*filters: "StatementFilter",
|
|
212
175
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
213
176
|
schema_type: None = None,
|
|
214
177
|
**kwargs: Any,
|
|
@@ -218,8 +181,7 @@ class PsycopgSyncDriver(
|
|
|
218
181
|
self,
|
|
219
182
|
sql: str,
|
|
220
183
|
parameters: "Optional[StatementParameterType]" = None,
|
|
221
|
-
|
|
222
|
-
*,
|
|
184
|
+
*filters: "StatementFilter",
|
|
223
185
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
224
186
|
schema_type: "type[ModelDTOT]",
|
|
225
187
|
**kwargs: Any,
|
|
@@ -228,8 +190,7 @@ class PsycopgSyncDriver(
|
|
|
228
190
|
self,
|
|
229
191
|
sql: str,
|
|
230
192
|
parameters: "Optional[StatementParameterType]" = None,
|
|
231
|
-
|
|
232
|
-
*,
|
|
193
|
+
*filters: "StatementFilter",
|
|
233
194
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
234
195
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
235
196
|
**kwargs: Any,
|
|
@@ -240,22 +201,19 @@ class PsycopgSyncDriver(
|
|
|
240
201
|
The first row of the query results.
|
|
241
202
|
"""
|
|
242
203
|
connection = self._connection(connection)
|
|
243
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
204
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
244
205
|
with self._with_cursor(connection) as cursor:
|
|
245
206
|
cursor.execute(sql, parameters)
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
return cast("ModelDTOT", schema_type(**cast("dict[str,Any]", row)))
|
|
250
|
-
return cast("dict[str,Any]", row)
|
|
207
|
+
result = cursor.fetchone()
|
|
208
|
+
result = self.check_not_found(result)
|
|
209
|
+
return self.to_schema(cast("dict[str, Any]", result), schema_type=schema_type)
|
|
251
210
|
|
|
252
211
|
@overload
|
|
253
212
|
def select_one_or_none(
|
|
254
213
|
self,
|
|
255
214
|
sql: str,
|
|
256
215
|
parameters: "Optional[StatementParameterType]" = None,
|
|
257
|
-
|
|
258
|
-
*,
|
|
216
|
+
*filters: "StatementFilter",
|
|
259
217
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
260
218
|
schema_type: None = None,
|
|
261
219
|
**kwargs: Any,
|
|
@@ -265,8 +223,7 @@ class PsycopgSyncDriver(
|
|
|
265
223
|
self,
|
|
266
224
|
sql: str,
|
|
267
225
|
parameters: "Optional[StatementParameterType]" = None,
|
|
268
|
-
|
|
269
|
-
*,
|
|
226
|
+
*filters: "StatementFilter",
|
|
270
227
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
271
228
|
schema_type: "type[ModelDTOT]",
|
|
272
229
|
**kwargs: Any,
|
|
@@ -275,8 +232,7 @@ class PsycopgSyncDriver(
|
|
|
275
232
|
self,
|
|
276
233
|
sql: str,
|
|
277
234
|
parameters: "Optional[StatementParameterType]" = None,
|
|
278
|
-
|
|
279
|
-
*,
|
|
235
|
+
*filters: "StatementFilter",
|
|
280
236
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
281
237
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
282
238
|
**kwargs: Any,
|
|
@@ -284,26 +240,23 @@ class PsycopgSyncDriver(
|
|
|
284
240
|
"""Fetch one row from the database.
|
|
285
241
|
|
|
286
242
|
Returns:
|
|
287
|
-
The first row of the query results.
|
|
243
|
+
The first row of the query results, or None if no results.
|
|
288
244
|
"""
|
|
289
245
|
connection = self._connection(connection)
|
|
290
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
246
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
291
247
|
with self._with_cursor(connection) as cursor:
|
|
292
248
|
cursor.execute(sql, parameters)
|
|
293
|
-
|
|
294
|
-
if
|
|
249
|
+
result = cursor.fetchone()
|
|
250
|
+
if result is None:
|
|
295
251
|
return None
|
|
296
|
-
|
|
297
|
-
return cast("ModelDTOT", schema_type(**cast("dict[str,Any]", row)))
|
|
298
|
-
return cast("dict[str,Any]", row)
|
|
252
|
+
return self.to_schema(cast("dict[str, Any]", result), schema_type=schema_type)
|
|
299
253
|
|
|
300
254
|
@overload
|
|
301
255
|
def select_value(
|
|
302
256
|
self,
|
|
303
257
|
sql: str,
|
|
304
258
|
parameters: "Optional[StatementParameterType]" = None,
|
|
305
|
-
|
|
306
|
-
*,
|
|
259
|
+
*filters: "StatementFilter",
|
|
307
260
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
308
261
|
schema_type: None = None,
|
|
309
262
|
**kwargs: Any,
|
|
@@ -313,8 +266,7 @@ class PsycopgSyncDriver(
|
|
|
313
266
|
self,
|
|
314
267
|
sql: str,
|
|
315
268
|
parameters: "Optional[StatementParameterType]" = None,
|
|
316
|
-
|
|
317
|
-
*,
|
|
269
|
+
*filters: "StatementFilter",
|
|
318
270
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
319
271
|
schema_type: "type[T]",
|
|
320
272
|
**kwargs: Any,
|
|
@@ -323,8 +275,7 @@ class PsycopgSyncDriver(
|
|
|
323
275
|
self,
|
|
324
276
|
sql: str,
|
|
325
277
|
parameters: "Optional[StatementParameterType]" = None,
|
|
326
|
-
|
|
327
|
-
*,
|
|
278
|
+
*filters: "StatementFilter",
|
|
328
279
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
329
280
|
schema_type: "Optional[type[T]]" = None,
|
|
330
281
|
**kwargs: Any,
|
|
@@ -332,27 +283,26 @@ class PsycopgSyncDriver(
|
|
|
332
283
|
"""Fetch a single value from the database.
|
|
333
284
|
|
|
334
285
|
Returns:
|
|
335
|
-
The first value from the first row of results
|
|
286
|
+
The first value from the first row of results.
|
|
336
287
|
"""
|
|
337
288
|
connection = self._connection(connection)
|
|
338
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
289
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
339
290
|
with self._with_cursor(connection) as cursor:
|
|
340
291
|
cursor.execute(sql, parameters)
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
if schema_type is
|
|
346
|
-
return
|
|
347
|
-
return
|
|
292
|
+
result = cursor.fetchone()
|
|
293
|
+
result = self.check_not_found(result)
|
|
294
|
+
|
|
295
|
+
value = next(iter(result.values())) # Get the first value from the row
|
|
296
|
+
if schema_type is None:
|
|
297
|
+
return value
|
|
298
|
+
return schema_type(value) # type: ignore[call-arg]
|
|
348
299
|
|
|
349
300
|
@overload
|
|
350
301
|
def select_value_or_none(
|
|
351
302
|
self,
|
|
352
303
|
sql: str,
|
|
353
304
|
parameters: "Optional[StatementParameterType]" = None,
|
|
354
|
-
|
|
355
|
-
*,
|
|
305
|
+
*filters: "StatementFilter",
|
|
356
306
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
357
307
|
schema_type: None = None,
|
|
358
308
|
**kwargs: Any,
|
|
@@ -362,8 +312,7 @@ class PsycopgSyncDriver(
|
|
|
362
312
|
self,
|
|
363
313
|
sql: str,
|
|
364
314
|
parameters: "Optional[StatementParameterType]" = None,
|
|
365
|
-
|
|
366
|
-
*,
|
|
315
|
+
*filters: "StatementFilter",
|
|
367
316
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
368
317
|
schema_type: "type[T]",
|
|
369
318
|
**kwargs: Any,
|
|
@@ -372,8 +321,7 @@ class PsycopgSyncDriver(
|
|
|
372
321
|
self,
|
|
373
322
|
sql: str,
|
|
374
323
|
parameters: "Optional[StatementParameterType]" = None,
|
|
375
|
-
|
|
376
|
-
*,
|
|
324
|
+
*filters: "StatementFilter",
|
|
377
325
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
378
326
|
schema_type: "Optional[type[T]]" = None,
|
|
379
327
|
**kwargs: Any,
|
|
@@ -384,35 +332,33 @@ class PsycopgSyncDriver(
|
|
|
384
332
|
The first value from the first row of results, or None if no results.
|
|
385
333
|
"""
|
|
386
334
|
connection = self._connection(connection)
|
|
387
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
335
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
388
336
|
with self._with_cursor(connection) as cursor:
|
|
389
337
|
cursor.execute(sql, parameters)
|
|
390
|
-
|
|
391
|
-
if
|
|
392
|
-
return None
|
|
393
|
-
val = next(iter(row.values())) if row else None
|
|
394
|
-
if val is None:
|
|
338
|
+
result = cursor.fetchone()
|
|
339
|
+
if result is None:
|
|
395
340
|
return None
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
341
|
+
|
|
342
|
+
value = next(iter(result.values())) # Get the first value from the row
|
|
343
|
+
if schema_type is None:
|
|
344
|
+
return value
|
|
345
|
+
return schema_type(value) # type: ignore[call-arg]
|
|
399
346
|
|
|
400
347
|
def insert_update_delete(
|
|
401
348
|
self,
|
|
402
349
|
sql: str,
|
|
403
350
|
parameters: "Optional[StatementParameterType]" = None,
|
|
404
|
-
|
|
405
|
-
*,
|
|
351
|
+
*filters: "StatementFilter",
|
|
406
352
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
407
353
|
**kwargs: Any,
|
|
408
354
|
) -> int:
|
|
409
|
-
"""
|
|
355
|
+
"""Insert, update, or delete data from the database.
|
|
410
356
|
|
|
411
357
|
Returns:
|
|
412
|
-
|
|
358
|
+
Row count affected by the operation.
|
|
413
359
|
"""
|
|
414
360
|
connection = self._connection(connection)
|
|
415
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
361
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
416
362
|
with self._with_cursor(connection) as cursor:
|
|
417
363
|
cursor.execute(sql, parameters)
|
|
418
364
|
return getattr(cursor, "rowcount", -1) # pyright: ignore[reportUnknownMemberType]
|
|
@@ -422,8 +368,7 @@ class PsycopgSyncDriver(
|
|
|
422
368
|
self,
|
|
423
369
|
sql: str,
|
|
424
370
|
parameters: "Optional[StatementParameterType]" = None,
|
|
425
|
-
|
|
426
|
-
*,
|
|
371
|
+
*filters: "StatementFilter",
|
|
427
372
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
428
373
|
schema_type: None = None,
|
|
429
374
|
**kwargs: Any,
|
|
@@ -433,8 +378,7 @@ class PsycopgSyncDriver(
|
|
|
433
378
|
self,
|
|
434
379
|
sql: str,
|
|
435
380
|
parameters: "Optional[StatementParameterType]" = None,
|
|
436
|
-
|
|
437
|
-
*,
|
|
381
|
+
*filters: "StatementFilter",
|
|
438
382
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
439
383
|
schema_type: "type[ModelDTOT]",
|
|
440
384
|
**kwargs: Any,
|
|
@@ -443,36 +387,28 @@ class PsycopgSyncDriver(
|
|
|
443
387
|
self,
|
|
444
388
|
sql: str,
|
|
445
389
|
parameters: "Optional[StatementParameterType]" = None,
|
|
446
|
-
|
|
447
|
-
*,
|
|
390
|
+
*filters: "StatementFilter",
|
|
448
391
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
449
392
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
450
393
|
**kwargs: Any,
|
|
451
|
-
) -> "
|
|
452
|
-
"""Insert, update, or delete data
|
|
394
|
+
) -> "Union[ModelDTOT, dict[str, Any]]":
|
|
395
|
+
"""Insert, update, or delete data with RETURNING clause.
|
|
453
396
|
|
|
454
397
|
Returns:
|
|
455
|
-
The
|
|
398
|
+
The returned row data, as either a model instance or dictionary.
|
|
456
399
|
"""
|
|
457
400
|
connection = self._connection(connection)
|
|
458
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
401
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
459
402
|
with self._with_cursor(connection) as cursor:
|
|
460
403
|
cursor.execute(sql, parameters)
|
|
461
404
|
result = cursor.fetchone()
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
return None
|
|
465
|
-
|
|
466
|
-
if schema_type is not None:
|
|
467
|
-
return cast("ModelDTOT", schema_type(**result)) # pyright: ignore[reportUnknownArgumentType]
|
|
468
|
-
return cast("dict[str, Any]", result) # pyright: ignore[reportUnknownArgumentType,reportUnknownVariableType]
|
|
405
|
+
result = self.check_not_found(result)
|
|
406
|
+
return self.to_schema(cast("dict[str, Any]", result), schema_type=schema_type)
|
|
469
407
|
|
|
470
408
|
def execute_script(
|
|
471
409
|
self,
|
|
472
410
|
sql: str,
|
|
473
411
|
parameters: "Optional[StatementParameterType]" = None,
|
|
474
|
-
/,
|
|
475
|
-
*,
|
|
476
412
|
connection: "Optional[PsycopgSyncConnection]" = None,
|
|
477
413
|
**kwargs: Any,
|
|
478
414
|
) -> str:
|
|
@@ -492,11 +428,11 @@ class PsycopgAsyncDriver(
|
|
|
492
428
|
PsycopgDriverBase,
|
|
493
429
|
SQLTranslatorMixin["PsycopgAsyncConnection"],
|
|
494
430
|
AsyncDriverAdapterProtocol["PsycopgAsyncConnection"],
|
|
431
|
+
ResultConverter,
|
|
495
432
|
):
|
|
496
433
|
"""Psycopg Async Driver Adapter."""
|
|
497
434
|
|
|
498
435
|
connection: "PsycopgAsyncConnection"
|
|
499
|
-
dialect: str = "postgres"
|
|
500
436
|
|
|
501
437
|
def __init__(self, connection: "PsycopgAsyncConnection") -> None:
|
|
502
438
|
self.connection = connection
|
|
@@ -516,8 +452,7 @@ class PsycopgAsyncDriver(
|
|
|
516
452
|
self,
|
|
517
453
|
sql: str,
|
|
518
454
|
parameters: "Optional[StatementParameterType]" = None,
|
|
519
|
-
|
|
520
|
-
*,
|
|
455
|
+
*filters: "StatementFilter",
|
|
521
456
|
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
522
457
|
schema_type: None = None,
|
|
523
458
|
**kwargs: Any,
|
|
@@ -527,8 +462,7 @@ class PsycopgAsyncDriver(
|
|
|
527
462
|
self,
|
|
528
463
|
sql: str,
|
|
529
464
|
parameters: "Optional[StatementParameterType]" = None,
|
|
530
|
-
|
|
531
|
-
*,
|
|
465
|
+
*filters: "StatementFilter",
|
|
532
466
|
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
533
467
|
schema_type: "type[ModelDTOT]",
|
|
534
468
|
**kwargs: Any,
|
|
@@ -537,10 +471,9 @@ class PsycopgAsyncDriver(
|
|
|
537
471
|
self,
|
|
538
472
|
sql: str,
|
|
539
473
|
parameters: "Optional[StatementParameterType]" = None,
|
|
540
|
-
|
|
541
|
-
*,
|
|
542
|
-
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
474
|
+
*filters: "StatementFilter",
|
|
543
475
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
476
|
+
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
544
477
|
**kwargs: Any,
|
|
545
478
|
) -> "Sequence[Union[ModelDTOT, dict[str, Any]]]":
|
|
546
479
|
"""Fetch data from the database.
|
|
@@ -549,25 +482,21 @@ class PsycopgAsyncDriver(
|
|
|
549
482
|
List of row data as either model instances or dictionaries.
|
|
550
483
|
"""
|
|
551
484
|
connection = self._connection(connection)
|
|
552
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
553
|
-
results: list[Union[ModelDTOT, dict[str, Any]]] = []
|
|
554
|
-
|
|
485
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
555
486
|
async with self._with_cursor(connection) as cursor:
|
|
556
487
|
await cursor.execute(sql, parameters)
|
|
557
488
|
results = await cursor.fetchall()
|
|
558
489
|
if not results:
|
|
559
490
|
return []
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
return [cast("dict[str,Any]", row) for row in results] # pyright: ignore[reportUnknownArgumentType]
|
|
491
|
+
|
|
492
|
+
return self.to_schema(cast("Sequence[dict[str, Any]]", results), schema_type=schema_type)
|
|
563
493
|
|
|
564
494
|
@overload
|
|
565
495
|
async def select_one(
|
|
566
496
|
self,
|
|
567
497
|
sql: str,
|
|
568
498
|
parameters: "Optional[StatementParameterType]" = None,
|
|
569
|
-
|
|
570
|
-
*,
|
|
499
|
+
*filters: "StatementFilter",
|
|
571
500
|
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
572
501
|
schema_type: None = None,
|
|
573
502
|
**kwargs: Any,
|
|
@@ -577,8 +506,7 @@ class PsycopgAsyncDriver(
|
|
|
577
506
|
self,
|
|
578
507
|
sql: str,
|
|
579
508
|
parameters: "Optional[StatementParameterType]" = None,
|
|
580
|
-
|
|
581
|
-
*,
|
|
509
|
+
*filters: "StatementFilter",
|
|
582
510
|
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
583
511
|
schema_type: "type[ModelDTOT]",
|
|
584
512
|
**kwargs: Any,
|
|
@@ -587,8 +515,7 @@ class PsycopgAsyncDriver(
|
|
|
587
515
|
self,
|
|
588
516
|
sql: str,
|
|
589
517
|
parameters: "Optional[StatementParameterType]" = None,
|
|
590
|
-
|
|
591
|
-
*,
|
|
518
|
+
*filters: "StatementFilter",
|
|
592
519
|
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
593
520
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
594
521
|
**kwargs: Any,
|
|
@@ -599,23 +526,19 @@ class PsycopgAsyncDriver(
|
|
|
599
526
|
The first row of the query results.
|
|
600
527
|
"""
|
|
601
528
|
connection = self._connection(connection)
|
|
602
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
603
|
-
|
|
529
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
604
530
|
async with self._with_cursor(connection) as cursor:
|
|
605
531
|
await cursor.execute(sql, parameters)
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
return cast("ModelDTOT", schema_type(**cast("dict[str,Any]", row)))
|
|
610
|
-
return cast("dict[str,Any]", row)
|
|
532
|
+
result = await cursor.fetchone()
|
|
533
|
+
result = self.check_not_found(result)
|
|
534
|
+
return self.to_schema(cast("dict[str, Any]", result), schema_type=schema_type)
|
|
611
535
|
|
|
612
536
|
@overload
|
|
613
537
|
async def select_one_or_none(
|
|
614
538
|
self,
|
|
615
539
|
sql: str,
|
|
616
540
|
parameters: "Optional[StatementParameterType]" = None,
|
|
617
|
-
|
|
618
|
-
*,
|
|
541
|
+
*filters: "StatementFilter",
|
|
619
542
|
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
620
543
|
schema_type: None = None,
|
|
621
544
|
**kwargs: Any,
|
|
@@ -625,8 +548,7 @@ class PsycopgAsyncDriver(
|
|
|
625
548
|
self,
|
|
626
549
|
sql: str,
|
|
627
550
|
parameters: "Optional[StatementParameterType]" = None,
|
|
628
|
-
|
|
629
|
-
*,
|
|
551
|
+
*filters: "StatementFilter",
|
|
630
552
|
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
631
553
|
schema_type: "type[ModelDTOT]",
|
|
632
554
|
**kwargs: Any,
|
|
@@ -635,8 +557,7 @@ class PsycopgAsyncDriver(
|
|
|
635
557
|
self,
|
|
636
558
|
sql: str,
|
|
637
559
|
parameters: "Optional[StatementParameterType]" = None,
|
|
638
|
-
|
|
639
|
-
*,
|
|
560
|
+
*filters: "StatementFilter",
|
|
640
561
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
641
562
|
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
642
563
|
**kwargs: Any,
|
|
@@ -644,27 +565,23 @@ class PsycopgAsyncDriver(
|
|
|
644
565
|
"""Fetch one row from the database.
|
|
645
566
|
|
|
646
567
|
Returns:
|
|
647
|
-
The first row of the query results.
|
|
568
|
+
The first row of the query results, or None if no results.
|
|
648
569
|
"""
|
|
649
570
|
connection = self._connection(connection)
|
|
650
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
651
|
-
|
|
571
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
652
572
|
async with self._with_cursor(connection) as cursor:
|
|
653
573
|
await cursor.execute(sql, parameters)
|
|
654
|
-
|
|
655
|
-
if
|
|
574
|
+
result = await cursor.fetchone()
|
|
575
|
+
if result is None:
|
|
656
576
|
return None
|
|
657
|
-
|
|
658
|
-
return cast("ModelDTOT", schema_type(**cast("dict[str,Any]", row)))
|
|
659
|
-
return cast("dict[str,Any]", row)
|
|
577
|
+
return self.to_schema(cast("dict[str, Any]", result), schema_type=schema_type)
|
|
660
578
|
|
|
661
579
|
@overload
|
|
662
580
|
async def select_value(
|
|
663
581
|
self,
|
|
664
582
|
sql: str,
|
|
665
583
|
parameters: "Optional[StatementParameterType]" = None,
|
|
666
|
-
|
|
667
|
-
*,
|
|
584
|
+
*filters: "StatementFilter",
|
|
668
585
|
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
669
586
|
schema_type: None = None,
|
|
670
587
|
**kwargs: Any,
|
|
@@ -674,8 +591,7 @@ class PsycopgAsyncDriver(
|
|
|
674
591
|
self,
|
|
675
592
|
sql: str,
|
|
676
593
|
parameters: "Optional[StatementParameterType]" = None,
|
|
677
|
-
|
|
678
|
-
*,
|
|
594
|
+
*filters: "StatementFilter",
|
|
679
595
|
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
680
596
|
schema_type: "type[T]",
|
|
681
597
|
**kwargs: Any,
|
|
@@ -684,8 +600,7 @@ class PsycopgAsyncDriver(
|
|
|
684
600
|
self,
|
|
685
601
|
sql: str,
|
|
686
602
|
parameters: "Optional[StatementParameterType]" = None,
|
|
687
|
-
|
|
688
|
-
*,
|
|
603
|
+
*filters: "StatementFilter",
|
|
689
604
|
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
690
605
|
schema_type: "Optional[type[T]]" = None,
|
|
691
606
|
**kwargs: Any,
|
|
@@ -693,27 +608,45 @@ class PsycopgAsyncDriver(
|
|
|
693
608
|
"""Fetch a single value from the database.
|
|
694
609
|
|
|
695
610
|
Returns:
|
|
696
|
-
The first value from the first row of results
|
|
611
|
+
The first value from the first row of results.
|
|
697
612
|
"""
|
|
698
613
|
connection = self._connection(connection)
|
|
699
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
700
|
-
|
|
614
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
701
615
|
async with self._with_cursor(connection) as cursor:
|
|
702
616
|
await cursor.execute(sql, parameters)
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
if schema_type is
|
|
708
|
-
return
|
|
709
|
-
return
|
|
617
|
+
result = await cursor.fetchone()
|
|
618
|
+
result = self.check_not_found(result)
|
|
619
|
+
|
|
620
|
+
value = next(iter(result.values())) # Get the first value from the row
|
|
621
|
+
if schema_type is None:
|
|
622
|
+
return value
|
|
623
|
+
return schema_type(value) # type: ignore[call-arg]
|
|
710
624
|
|
|
625
|
+
@overload
|
|
626
|
+
async def select_value_or_none(
|
|
627
|
+
self,
|
|
628
|
+
sql: str,
|
|
629
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
630
|
+
*filters: "StatementFilter",
|
|
631
|
+
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
632
|
+
schema_type: None = None,
|
|
633
|
+
**kwargs: Any,
|
|
634
|
+
) -> "Optional[Any]": ...
|
|
635
|
+
@overload
|
|
711
636
|
async def select_value_or_none(
|
|
712
637
|
self,
|
|
713
638
|
sql: str,
|
|
714
639
|
parameters: "Optional[StatementParameterType]" = None,
|
|
715
|
-
|
|
716
|
-
|
|
640
|
+
*filters: "StatementFilter",
|
|
641
|
+
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
642
|
+
schema_type: "type[T]",
|
|
643
|
+
**kwargs: Any,
|
|
644
|
+
) -> "Optional[T]": ...
|
|
645
|
+
async def select_value_or_none(
|
|
646
|
+
self,
|
|
647
|
+
sql: str,
|
|
648
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
649
|
+
*filters: "StatementFilter",
|
|
717
650
|
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
718
651
|
schema_type: "Optional[type[T]]" = None,
|
|
719
652
|
**kwargs: Any,
|
|
@@ -724,52 +657,43 @@ class PsycopgAsyncDriver(
|
|
|
724
657
|
The first value from the first row of results, or None if no results.
|
|
725
658
|
"""
|
|
726
659
|
connection = self._connection(connection)
|
|
727
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
728
|
-
|
|
660
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
729
661
|
async with self._with_cursor(connection) as cursor:
|
|
730
662
|
await cursor.execute(sql, parameters)
|
|
731
|
-
|
|
732
|
-
if
|
|
733
|
-
return None
|
|
734
|
-
val = next(iter(row.values())) if row else None
|
|
735
|
-
if val is None:
|
|
663
|
+
result = await cursor.fetchone()
|
|
664
|
+
if result is None:
|
|
736
665
|
return None
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
666
|
+
|
|
667
|
+
value = next(iter(result.values())) # Get the first value from the row
|
|
668
|
+
if schema_type is None:
|
|
669
|
+
return value
|
|
670
|
+
return schema_type(value) # type: ignore[call-arg]
|
|
740
671
|
|
|
741
672
|
async def insert_update_delete(
|
|
742
673
|
self,
|
|
743
674
|
sql: str,
|
|
744
675
|
parameters: "Optional[StatementParameterType]" = None,
|
|
745
|
-
|
|
746
|
-
*,
|
|
676
|
+
*filters: "StatementFilter",
|
|
747
677
|
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
748
678
|
**kwargs: Any,
|
|
749
679
|
) -> int:
|
|
750
|
-
"""
|
|
680
|
+
"""Insert, update, or delete data from the database.
|
|
751
681
|
|
|
752
682
|
Returns:
|
|
753
|
-
|
|
683
|
+
Row count affected by the operation.
|
|
754
684
|
"""
|
|
755
685
|
connection = self._connection(connection)
|
|
756
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
757
|
-
|
|
686
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
758
687
|
async with self._with_cursor(connection) as cursor:
|
|
759
688
|
await cursor.execute(sql, parameters)
|
|
760
|
-
|
|
761
|
-
rowcount = int(cursor.rowcount)
|
|
762
|
-
except (TypeError, ValueError):
|
|
763
|
-
rowcount = -1
|
|
764
|
-
return rowcount
|
|
689
|
+
return getattr(cursor, "rowcount", -1) # pyright: ignore[reportUnknownMemberType]
|
|
765
690
|
|
|
766
691
|
@overload
|
|
767
692
|
async def insert_update_delete_returning(
|
|
768
693
|
self,
|
|
769
694
|
sql: str,
|
|
770
695
|
parameters: "Optional[StatementParameterType]" = None,
|
|
771
|
-
|
|
772
|
-
*,
|
|
696
|
+
*filters: "StatementFilter",
|
|
773
697
|
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
774
698
|
schema_type: None = None,
|
|
775
699
|
**kwargs: Any,
|
|
@@ -779,8 +703,7 @@ class PsycopgAsyncDriver(
|
|
|
779
703
|
self,
|
|
780
704
|
sql: str,
|
|
781
705
|
parameters: "Optional[StatementParameterType]" = None,
|
|
782
|
-
|
|
783
|
-
*,
|
|
706
|
+
*filters: "StatementFilter",
|
|
784
707
|
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
785
708
|
schema_type: "type[ModelDTOT]",
|
|
786
709
|
**kwargs: Any,
|
|
@@ -789,37 +712,28 @@ class PsycopgAsyncDriver(
|
|
|
789
712
|
self,
|
|
790
713
|
sql: str,
|
|
791
714
|
parameters: "Optional[StatementParameterType]" = None,
|
|
792
|
-
|
|
793
|
-
*,
|
|
715
|
+
*filters: "StatementFilter",
|
|
794
716
|
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
795
717
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
796
718
|
**kwargs: Any,
|
|
797
|
-
) -> "
|
|
798
|
-
"""Insert, update, or delete data
|
|
719
|
+
) -> "Union[ModelDTOT, dict[str, Any]]":
|
|
720
|
+
"""Insert, update, or delete data with RETURNING clause.
|
|
799
721
|
|
|
800
722
|
Returns:
|
|
801
|
-
The
|
|
723
|
+
The returned row data, as either a model instance or dictionary.
|
|
802
724
|
"""
|
|
803
725
|
connection = self._connection(connection)
|
|
804
|
-
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
805
|
-
|
|
726
|
+
sql, parameters = self._process_sql_params(sql, parameters, *filters, **kwargs)
|
|
806
727
|
async with self._with_cursor(connection) as cursor:
|
|
807
728
|
await cursor.execute(sql, parameters)
|
|
808
729
|
result = await cursor.fetchone()
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
return None
|
|
812
|
-
|
|
813
|
-
if schema_type is not None:
|
|
814
|
-
return cast("ModelDTOT", schema_type(**result)) # pyright: ignore[reportUnknownArgumentType]
|
|
815
|
-
return cast("dict[str, Any]", result) # pyright: ignore[reportUnknownArgumentType,reportUnknownVariableType]
|
|
730
|
+
result = self.check_not_found(result)
|
|
731
|
+
return self.to_schema(cast("dict[str, Any]", result), schema_type=schema_type)
|
|
816
732
|
|
|
817
733
|
async def execute_script(
|
|
818
734
|
self,
|
|
819
735
|
sql: str,
|
|
820
736
|
parameters: "Optional[StatementParameterType]" = None,
|
|
821
|
-
/,
|
|
822
|
-
*,
|
|
823
737
|
connection: "Optional[PsycopgAsyncConnection]" = None,
|
|
824
738
|
**kwargs: Any,
|
|
825
739
|
) -> str:
|
|
@@ -830,7 +744,6 @@ class PsycopgAsyncDriver(
|
|
|
830
744
|
"""
|
|
831
745
|
connection = self._connection(connection)
|
|
832
746
|
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
833
|
-
|
|
834
747
|
async with self._with_cursor(connection) as cursor:
|
|
835
748
|
await cursor.execute(sql, parameters)
|
|
836
749
|
return str(cursor.statusmessage) if cursor.statusmessage is not None else "DONE"
|