sqlspec 0.8.0__py3-none-any.whl → 0.9.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/_typing.py +39 -6
- sqlspec/adapters/adbc/__init__.py +2 -2
- sqlspec/adapters/adbc/config.py +34 -11
- sqlspec/adapters/adbc/driver.py +302 -111
- sqlspec/adapters/aiosqlite/__init__.py +2 -2
- sqlspec/adapters/aiosqlite/config.py +2 -2
- sqlspec/adapters/aiosqlite/driver.py +164 -42
- sqlspec/adapters/asyncmy/__init__.py +3 -3
- sqlspec/adapters/asyncmy/config.py +11 -12
- sqlspec/adapters/asyncmy/driver.py +161 -37
- sqlspec/adapters/asyncpg/__init__.py +5 -5
- sqlspec/adapters/asyncpg/config.py +17 -19
- sqlspec/adapters/asyncpg/driver.py +386 -96
- sqlspec/adapters/duckdb/__init__.py +2 -2
- sqlspec/adapters/duckdb/config.py +2 -2
- sqlspec/adapters/duckdb/driver.py +190 -60
- sqlspec/adapters/oracledb/__init__.py +8 -8
- sqlspec/adapters/oracledb/config/__init__.py +6 -6
- sqlspec/adapters/oracledb/config/_asyncio.py +9 -10
- sqlspec/adapters/oracledb/config/_sync.py +8 -9
- sqlspec/adapters/oracledb/driver.py +384 -45
- sqlspec/adapters/psqlpy/__init__.py +0 -0
- sqlspec/adapters/psqlpy/config.py +250 -0
- sqlspec/adapters/psqlpy/driver.py +481 -0
- sqlspec/adapters/psycopg/__init__.py +10 -5
- sqlspec/adapters/psycopg/config/__init__.py +6 -6
- sqlspec/adapters/psycopg/config/_async.py +12 -12
- sqlspec/adapters/psycopg/config/_sync.py +13 -13
- sqlspec/adapters/psycopg/driver.py +432 -222
- sqlspec/adapters/sqlite/__init__.py +2 -2
- sqlspec/adapters/sqlite/config.py +2 -2
- sqlspec/adapters/sqlite/driver.py +176 -72
- sqlspec/base.py +687 -161
- sqlspec/exceptions.py +30 -0
- sqlspec/extensions/litestar/config.py +6 -0
- sqlspec/extensions/litestar/handlers.py +25 -0
- sqlspec/extensions/litestar/plugin.py +8 -1
- sqlspec/statement.py +373 -0
- sqlspec/typing.py +10 -1
- {sqlspec-0.8.0.dist-info → sqlspec-0.9.1.dist-info}/METADATA +144 -2
- sqlspec-0.9.1.dist-info/RECORD +61 -0
- sqlspec-0.8.0.dist-info/RECORD +0 -57
- {sqlspec-0.8.0.dist-info → sqlspec-0.9.1.dist-info}/WHEEL +0 -0
- {sqlspec-0.8.0.dist-info → sqlspec-0.9.1.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.8.0.dist-info → sqlspec-0.9.1.dist-info}/licenses/NOTICE +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# type: ignore
|
|
2
|
-
from collections.abc import AsyncGenerator
|
|
2
|
+
from collections.abc import AsyncGenerator, Sequence
|
|
3
3
|
from contextlib import asynccontextmanager
|
|
4
|
-
from typing import TYPE_CHECKING, Any, Optional, Union, cast
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Optional, Union, cast, overload
|
|
5
5
|
|
|
6
6
|
from sqlspec.base import AsyncDriverAdapterProtocol, T
|
|
7
7
|
|
|
@@ -18,6 +18,7 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
18
18
|
"""Asyncmy MySQL/MariaDB Driver Adapter."""
|
|
19
19
|
|
|
20
20
|
connection: "Connection"
|
|
21
|
+
dialect: str = "mysql"
|
|
21
22
|
|
|
22
23
|
def __init__(self, connection: "Connection") -> None:
|
|
23
24
|
self.connection = connection
|
|
@@ -35,21 +36,46 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
35
36
|
finally:
|
|
36
37
|
await cursor.close()
|
|
37
38
|
|
|
39
|
+
# --- Public API Methods --- #
|
|
40
|
+
@overload
|
|
41
|
+
async def select(
|
|
42
|
+
self,
|
|
43
|
+
sql: str,
|
|
44
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
45
|
+
/,
|
|
46
|
+
*,
|
|
47
|
+
connection: "Optional[Connection]" = None,
|
|
48
|
+
schema_type: None = None,
|
|
49
|
+
**kwargs: Any,
|
|
50
|
+
) -> "Sequence[dict[str, Any]]": ...
|
|
51
|
+
@overload
|
|
52
|
+
async def select(
|
|
53
|
+
self,
|
|
54
|
+
sql: str,
|
|
55
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
56
|
+
/,
|
|
57
|
+
*,
|
|
58
|
+
connection: "Optional[Connection]" = None,
|
|
59
|
+
schema_type: "type[ModelDTOT]",
|
|
60
|
+
**kwargs: Any,
|
|
61
|
+
) -> "Sequence[ModelDTOT]": ...
|
|
38
62
|
async def select(
|
|
39
63
|
self,
|
|
40
64
|
sql: str,
|
|
41
65
|
parameters: Optional["StatementParameterType"] = None,
|
|
42
66
|
/,
|
|
67
|
+
*,
|
|
43
68
|
connection: Optional["Connection"] = None,
|
|
44
69
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
45
|
-
|
|
70
|
+
**kwargs: Any,
|
|
71
|
+
) -> "Sequence[Union[ModelDTOT, dict[str, Any]]]":
|
|
46
72
|
"""Fetch data from the database.
|
|
47
73
|
|
|
48
74
|
Returns:
|
|
49
75
|
List of row data as either model instances or dictionaries.
|
|
50
76
|
"""
|
|
51
77
|
connection = self._connection(connection)
|
|
52
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
78
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
53
79
|
async with self._with_cursor(connection) as cursor:
|
|
54
80
|
await cursor.execute(sql, parameters)
|
|
55
81
|
results = await cursor.fetchall()
|
|
@@ -60,13 +86,37 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
60
86
|
return [dict(zip(column_names, row)) for row in results]
|
|
61
87
|
return [schema_type(**dict(zip(column_names, row))) for row in results]
|
|
62
88
|
|
|
89
|
+
@overload
|
|
90
|
+
async def select_one(
|
|
91
|
+
self,
|
|
92
|
+
sql: str,
|
|
93
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
94
|
+
/,
|
|
95
|
+
*,
|
|
96
|
+
connection: "Optional[Connection]" = None,
|
|
97
|
+
schema_type: None = None,
|
|
98
|
+
**kwargs: Any,
|
|
99
|
+
) -> "dict[str, Any]": ...
|
|
100
|
+
@overload
|
|
101
|
+
async def select_one(
|
|
102
|
+
self,
|
|
103
|
+
sql: str,
|
|
104
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
105
|
+
/,
|
|
106
|
+
*,
|
|
107
|
+
connection: "Optional[Connection]" = None,
|
|
108
|
+
schema_type: "type[ModelDTOT]",
|
|
109
|
+
**kwargs: Any,
|
|
110
|
+
) -> "ModelDTOT": ...
|
|
63
111
|
async def select_one(
|
|
64
112
|
self,
|
|
65
113
|
sql: str,
|
|
66
114
|
parameters: Optional["StatementParameterType"] = None,
|
|
67
115
|
/,
|
|
116
|
+
*,
|
|
68
117
|
connection: Optional["Connection"] = None,
|
|
69
118
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
119
|
+
**kwargs: Any,
|
|
70
120
|
) -> "Union[ModelDTOT, dict[str, Any]]":
|
|
71
121
|
"""Fetch one row from the database.
|
|
72
122
|
|
|
@@ -74,7 +124,7 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
74
124
|
The first row of the query results.
|
|
75
125
|
"""
|
|
76
126
|
connection = self._connection(connection)
|
|
77
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
127
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
78
128
|
async with self._with_cursor(connection) as cursor:
|
|
79
129
|
await cursor.execute(sql, parameters)
|
|
80
130
|
result = await cursor.fetchone()
|
|
@@ -84,13 +134,37 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
84
134
|
return dict(zip(column_names, result))
|
|
85
135
|
return cast("ModelDTOT", schema_type(**dict(zip(column_names, result))))
|
|
86
136
|
|
|
137
|
+
@overload
|
|
138
|
+
async def select_one_or_none(
|
|
139
|
+
self,
|
|
140
|
+
sql: str,
|
|
141
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
142
|
+
/,
|
|
143
|
+
*,
|
|
144
|
+
connection: "Optional[Connection]" = None,
|
|
145
|
+
schema_type: None = None,
|
|
146
|
+
**kwargs: Any,
|
|
147
|
+
) -> "Optional[dict[str, Any]]": ...
|
|
148
|
+
@overload
|
|
149
|
+
async def select_one_or_none(
|
|
150
|
+
self,
|
|
151
|
+
sql: str,
|
|
152
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
153
|
+
/,
|
|
154
|
+
*,
|
|
155
|
+
connection: "Optional[Connection]" = None,
|
|
156
|
+
schema_type: "type[ModelDTOT]",
|
|
157
|
+
**kwargs: Any,
|
|
158
|
+
) -> "Optional[ModelDTOT]": ...
|
|
87
159
|
async def select_one_or_none(
|
|
88
160
|
self,
|
|
89
161
|
sql: str,
|
|
90
162
|
parameters: Optional["StatementParameterType"] = None,
|
|
91
163
|
/,
|
|
164
|
+
*,
|
|
92
165
|
connection: Optional["Connection"] = None,
|
|
93
166
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
167
|
+
**kwargs: Any,
|
|
94
168
|
) -> "Optional[Union[ModelDTOT, dict[str, Any]]]":
|
|
95
169
|
"""Fetch one row from the database.
|
|
96
170
|
|
|
@@ -98,7 +172,7 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
98
172
|
The first row of the query results.
|
|
99
173
|
"""
|
|
100
174
|
connection = self._connection(connection)
|
|
101
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
175
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
102
176
|
async with self._with_cursor(connection) as cursor:
|
|
103
177
|
await cursor.execute(sql, parameters)
|
|
104
178
|
result = await cursor.fetchone()
|
|
@@ -109,13 +183,37 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
109
183
|
return dict(zip(column_names, result))
|
|
110
184
|
return cast("ModelDTOT", schema_type(**dict(zip(column_names, result))))
|
|
111
185
|
|
|
186
|
+
@overload
|
|
187
|
+
async def select_value(
|
|
188
|
+
self,
|
|
189
|
+
sql: str,
|
|
190
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
191
|
+
/,
|
|
192
|
+
*,
|
|
193
|
+
connection: "Optional[Connection]" = None,
|
|
194
|
+
schema_type: None = None,
|
|
195
|
+
**kwargs: Any,
|
|
196
|
+
) -> "Any": ...
|
|
197
|
+
@overload
|
|
198
|
+
async def select_value(
|
|
199
|
+
self,
|
|
200
|
+
sql: str,
|
|
201
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
202
|
+
/,
|
|
203
|
+
*,
|
|
204
|
+
connection: "Optional[Connection]" = None,
|
|
205
|
+
schema_type: "type[T]",
|
|
206
|
+
**kwargs: Any,
|
|
207
|
+
) -> "T": ...
|
|
112
208
|
async def select_value(
|
|
113
209
|
self,
|
|
114
210
|
sql: str,
|
|
115
211
|
parameters: "Optional[StatementParameterType]" = None,
|
|
116
212
|
/,
|
|
213
|
+
*,
|
|
117
214
|
connection: "Optional[Connection]" = None,
|
|
118
215
|
schema_type: "Optional[type[T]]" = None,
|
|
216
|
+
**kwargs: Any,
|
|
119
217
|
) -> "Union[T, Any]":
|
|
120
218
|
"""Fetch a single value from the database.
|
|
121
219
|
|
|
@@ -123,7 +221,7 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
123
221
|
The first value from the first row of results, or None if no results.
|
|
124
222
|
"""
|
|
125
223
|
connection = self._connection(connection)
|
|
126
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
224
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
127
225
|
|
|
128
226
|
async with self._with_cursor(connection) as cursor:
|
|
129
227
|
await cursor.execute(sql, parameters)
|
|
@@ -135,13 +233,37 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
135
233
|
return schema_type(value) # type: ignore[call-arg]
|
|
136
234
|
return value
|
|
137
235
|
|
|
236
|
+
@overload
|
|
138
237
|
async def select_value_or_none(
|
|
139
238
|
self,
|
|
140
239
|
sql: str,
|
|
141
240
|
parameters: "Optional[StatementParameterType]" = None,
|
|
142
241
|
/,
|
|
242
|
+
*,
|
|
243
|
+
connection: "Optional[Connection]" = None,
|
|
244
|
+
schema_type: None = None,
|
|
245
|
+
**kwargs: Any,
|
|
246
|
+
) -> "Optional[Any]": ...
|
|
247
|
+
@overload
|
|
248
|
+
async def select_value_or_none(
|
|
249
|
+
self,
|
|
250
|
+
sql: str,
|
|
251
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
252
|
+
/,
|
|
253
|
+
*,
|
|
254
|
+
connection: "Optional[Connection]" = None,
|
|
255
|
+
schema_type: "type[T]",
|
|
256
|
+
**kwargs: Any,
|
|
257
|
+
) -> "Optional[T]": ...
|
|
258
|
+
async def select_value_or_none(
|
|
259
|
+
self,
|
|
260
|
+
sql: str,
|
|
261
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
262
|
+
/,
|
|
263
|
+
*,
|
|
143
264
|
connection: "Optional[Connection]" = None,
|
|
144
265
|
schema_type: "Optional[type[T]]" = None,
|
|
266
|
+
**kwargs: Any,
|
|
145
267
|
) -> "Optional[Union[T, Any]]":
|
|
146
268
|
"""Fetch a single value from the database.
|
|
147
269
|
|
|
@@ -149,7 +271,7 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
149
271
|
The first value from the first row of results, or None if no results.
|
|
150
272
|
"""
|
|
151
273
|
connection = self._connection(connection)
|
|
152
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
274
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
153
275
|
|
|
154
276
|
async with self._with_cursor(connection) as cursor:
|
|
155
277
|
await cursor.execute(sql, parameters)
|
|
@@ -168,7 +290,9 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
168
290
|
sql: str,
|
|
169
291
|
parameters: Optional["StatementParameterType"] = None,
|
|
170
292
|
/,
|
|
293
|
+
*,
|
|
171
294
|
connection: Optional["Connection"] = None,
|
|
295
|
+
**kwargs: Any,
|
|
172
296
|
) -> int:
|
|
173
297
|
"""Insert, update, or delete data from the database.
|
|
174
298
|
|
|
@@ -176,19 +300,43 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
176
300
|
Row count affected by the operation.
|
|
177
301
|
"""
|
|
178
302
|
connection = self._connection(connection)
|
|
179
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
303
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
180
304
|
|
|
181
305
|
async with self._with_cursor(connection) as cursor:
|
|
182
306
|
await cursor.execute(sql, parameters)
|
|
183
307
|
return cursor.rowcount
|
|
184
308
|
|
|
309
|
+
@overload
|
|
310
|
+
async def insert_update_delete_returning(
|
|
311
|
+
self,
|
|
312
|
+
sql: str,
|
|
313
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
314
|
+
/,
|
|
315
|
+
*,
|
|
316
|
+
connection: "Optional[Connection]" = None,
|
|
317
|
+
schema_type: None = None,
|
|
318
|
+
**kwargs: Any,
|
|
319
|
+
) -> "dict[str, Any]": ...
|
|
320
|
+
@overload
|
|
321
|
+
async def insert_update_delete_returning(
|
|
322
|
+
self,
|
|
323
|
+
sql: str,
|
|
324
|
+
parameters: "Optional[StatementParameterType]" = None,
|
|
325
|
+
/,
|
|
326
|
+
*,
|
|
327
|
+
connection: "Optional[Connection]" = None,
|
|
328
|
+
schema_type: "type[ModelDTOT]",
|
|
329
|
+
**kwargs: Any,
|
|
330
|
+
) -> "ModelDTOT": ...
|
|
185
331
|
async def insert_update_delete_returning(
|
|
186
332
|
self,
|
|
187
333
|
sql: str,
|
|
188
334
|
parameters: Optional["StatementParameterType"] = None,
|
|
189
335
|
/,
|
|
336
|
+
*,
|
|
190
337
|
connection: Optional["Connection"] = None,
|
|
191
338
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
339
|
+
**kwargs: Any,
|
|
192
340
|
) -> "Optional[Union[dict[str, Any], ModelDTOT]]":
|
|
193
341
|
"""Insert, update, or delete data from the database and return result.
|
|
194
342
|
|
|
@@ -196,7 +344,7 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
196
344
|
The first row of results.
|
|
197
345
|
"""
|
|
198
346
|
connection = self._connection(connection)
|
|
199
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
347
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
200
348
|
column_names: list[str] = []
|
|
201
349
|
|
|
202
350
|
async with self._with_cursor(connection) as cursor:
|
|
@@ -214,7 +362,9 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
214
362
|
sql: str,
|
|
215
363
|
parameters: Optional["StatementParameterType"] = None,
|
|
216
364
|
/,
|
|
365
|
+
*,
|
|
217
366
|
connection: Optional["Connection"] = None,
|
|
367
|
+
**kwargs: Any,
|
|
218
368
|
) -> str:
|
|
219
369
|
"""Execute a script.
|
|
220
370
|
|
|
@@ -222,34 +372,8 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
222
372
|
Status message for the operation.
|
|
223
373
|
"""
|
|
224
374
|
connection = self._connection(connection)
|
|
225
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
375
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
226
376
|
|
|
227
377
|
async with self._with_cursor(connection) as cursor:
|
|
228
378
|
await cursor.execute(sql, parameters)
|
|
229
379
|
return "DONE"
|
|
230
|
-
|
|
231
|
-
async def execute_script_returning(
|
|
232
|
-
self,
|
|
233
|
-
sql: str,
|
|
234
|
-
parameters: Optional["StatementParameterType"] = None,
|
|
235
|
-
/,
|
|
236
|
-
connection: Optional["Connection"] = None,
|
|
237
|
-
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
238
|
-
) -> "Optional[Union[dict[str, Any], ModelDTOT]]":
|
|
239
|
-
"""Execute a script and return result.
|
|
240
|
-
|
|
241
|
-
Returns:
|
|
242
|
-
The first row of results.
|
|
243
|
-
"""
|
|
244
|
-
connection = self._connection(connection)
|
|
245
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
246
|
-
|
|
247
|
-
async with self._with_cursor(connection) as cursor:
|
|
248
|
-
await cursor.execute(sql, parameters)
|
|
249
|
-
result = await cursor.fetchone()
|
|
250
|
-
if result is None:
|
|
251
|
-
return None
|
|
252
|
-
column_names = [c[0] for c in cursor.description or []]
|
|
253
|
-
if schema_type is not None:
|
|
254
|
-
return cast("ModelDTOT", schema_type(**dict(zip(column_names, result))))
|
|
255
|
-
return dict(zip(column_names, result))
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
from sqlspec.adapters.asyncpg.config import
|
|
2
|
-
from sqlspec.adapters.asyncpg.driver import AsyncpgDriver
|
|
1
|
+
from sqlspec.adapters.asyncpg.config import AsyncpgConfig, AsyncpgPoolConfig
|
|
2
|
+
from sqlspec.adapters.asyncpg.driver import AsyncpgConnection, AsyncpgDriver
|
|
3
3
|
|
|
4
4
|
__all__ = (
|
|
5
|
-
"
|
|
5
|
+
"AsyncpgConfig",
|
|
6
|
+
"AsyncpgConnection",
|
|
6
7
|
"AsyncpgDriver",
|
|
7
|
-
"
|
|
8
|
-
"PgConnection",
|
|
8
|
+
"AsyncpgPoolConfig",
|
|
9
9
|
)
|
|
@@ -5,10 +5,9 @@ from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union
|
|
|
5
5
|
from asyncpg import Record
|
|
6
6
|
from asyncpg import create_pool as asyncpg_create_pool
|
|
7
7
|
from asyncpg.pool import PoolConnectionProxy
|
|
8
|
-
from typing_extensions import TypeAlias
|
|
9
8
|
|
|
10
9
|
from sqlspec._serialization import decode_json, encode_json
|
|
11
|
-
from sqlspec.adapters.asyncpg.driver import AsyncpgDriver
|
|
10
|
+
from sqlspec.adapters.asyncpg.driver import AsyncpgConnection, AsyncpgDriver
|
|
12
11
|
from sqlspec.base import AsyncDatabaseConfig, GenericPoolConfig
|
|
13
12
|
from sqlspec.exceptions import ImproperConfigurationError
|
|
14
13
|
from sqlspec.typing import Empty, EmptyType, dataclass_to_dict
|
|
@@ -22,18 +21,16 @@ if TYPE_CHECKING:
|
|
|
22
21
|
|
|
23
22
|
|
|
24
23
|
__all__ = (
|
|
25
|
-
"
|
|
26
|
-
"
|
|
24
|
+
"AsyncpgConfig",
|
|
25
|
+
"AsyncpgPoolConfig",
|
|
27
26
|
)
|
|
28
27
|
|
|
29
28
|
|
|
30
29
|
T = TypeVar("T")
|
|
31
30
|
|
|
32
|
-
PgConnection: TypeAlias = "Union[Connection[Any], PoolConnectionProxy[Any]]"
|
|
33
|
-
|
|
34
31
|
|
|
35
32
|
@dataclass
|
|
36
|
-
class
|
|
33
|
+
class AsyncpgPoolConfig(GenericPoolConfig):
|
|
37
34
|
"""Configuration for Asyncpg's :class:`Pool <asyncpg.pool.Pool>`.
|
|
38
35
|
|
|
39
36
|
For details see: https://magicstack.github.io/asyncpg/current/api/index.html#connection-pools
|
|
@@ -73,23 +70,25 @@ class AsyncpgPool(GenericPoolConfig):
|
|
|
73
70
|
|
|
74
71
|
|
|
75
72
|
@dataclass
|
|
76
|
-
class
|
|
73
|
+
class AsyncpgConfig(AsyncDatabaseConfig["AsyncpgConnection", "Pool", "AsyncpgDriver"]): # pyright: ignore[reportMissingTypeArgument]
|
|
77
74
|
"""Asyncpg Configuration."""
|
|
78
75
|
|
|
79
|
-
pool_config: "Optional[
|
|
76
|
+
pool_config: "Optional[AsyncpgPoolConfig]" = field(default=None)
|
|
80
77
|
"""Asyncpg Pool configuration"""
|
|
81
|
-
json_deserializer: "Callable[[str], Any]" = decode_json
|
|
78
|
+
json_deserializer: "Callable[[str], Any]" = field(hash=False, default=decode_json)
|
|
82
79
|
"""For dialects that support the :class:`JSON <sqlalchemy.types.JSON>` datatype, this is a Python callable that will
|
|
83
80
|
convert a JSON string to a Python object. By default, this is set to SQLSpec's
|
|
84
81
|
:attr:`decode_json() <sqlspec._serialization.decode_json>` function."""
|
|
85
|
-
json_serializer: "Callable[[Any], str]" = encode_json
|
|
82
|
+
json_serializer: "Callable[[Any], str]" = field(hash=False, default=encode_json)
|
|
86
83
|
"""For dialects that support the JSON datatype, this is a Python callable that will render a given object as JSON.
|
|
87
84
|
By default, SQLSpec's :attr:`encode_json() <sqlspec._serialization.encode_json>` is used."""
|
|
88
|
-
connection_type: "type[
|
|
85
|
+
connection_type: "type[AsyncpgConnection]" = field(
|
|
86
|
+
hash=False, init=False, default_factory=lambda: PoolConnectionProxy
|
|
87
|
+
)
|
|
89
88
|
"""Type of the connection object"""
|
|
90
|
-
driver_type: "type[AsyncpgDriver]" = field(init=False, default_factory=lambda: AsyncpgDriver) # type: ignore[type-abstract,unused-ignore]
|
|
89
|
+
driver_type: "type[AsyncpgDriver]" = field(hash=False, init=False, default_factory=lambda: AsyncpgDriver) # type: ignore[type-abstract,unused-ignore]
|
|
91
90
|
"""Type of the driver object"""
|
|
92
|
-
pool_instance: "Optional[Pool[Any]]" = None
|
|
91
|
+
pool_instance: "Optional[Pool[Any]]" = field(hash=False, default=None)
|
|
93
92
|
"""The connection pool instance. If set, this will be used instead of creating a new pool."""
|
|
94
93
|
|
|
95
94
|
@property
|
|
@@ -174,8 +173,8 @@ class Asyncpg(AsyncDatabaseConfig["PgConnection", "Pool", "AsyncpgDriver"]): #
|
|
|
174
173
|
"""
|
|
175
174
|
return self.create_pool() # pyright: ignore[reportUnknownMemberType,reportUnknownVariableType]
|
|
176
175
|
|
|
177
|
-
async def create_connection(self) -> "
|
|
178
|
-
"""Create and return a new asyncpg connection.
|
|
176
|
+
async def create_connection(self) -> "AsyncpgConnection":
|
|
177
|
+
"""Create and return a new asyncpg connection from the pool.
|
|
179
178
|
|
|
180
179
|
Returns:
|
|
181
180
|
A Connection instance.
|
|
@@ -184,9 +183,8 @@ class Asyncpg(AsyncDatabaseConfig["PgConnection", "Pool", "AsyncpgDriver"]): #
|
|
|
184
183
|
ImproperConfigurationError: If the connection could not be created.
|
|
185
184
|
"""
|
|
186
185
|
try:
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
return await asyncpg.connect(**self.connection_config_dict) # type: ignore[no-any-return]
|
|
186
|
+
pool = await self.provide_pool()
|
|
187
|
+
return await pool.acquire()
|
|
190
188
|
except Exception as e:
|
|
191
189
|
msg = f"Could not configure the asyncpg connection. Error: {e!s}"
|
|
192
190
|
raise ImproperConfigurationError(msg) from e
|