sqlspec 0.8.0__py3-none-any.whl → 0.9.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/_typing.py +39 -6
- sqlspec/adapters/adbc/__init__.py +2 -2
- sqlspec/adapters/adbc/config.py +34 -11
- sqlspec/adapters/adbc/driver.py +167 -108
- sqlspec/adapters/aiosqlite/__init__.py +2 -2
- sqlspec/adapters/aiosqlite/config.py +2 -2
- sqlspec/adapters/aiosqlite/driver.py +28 -39
- sqlspec/adapters/asyncmy/__init__.py +3 -3
- sqlspec/adapters/asyncmy/config.py +11 -12
- sqlspec/adapters/asyncmy/driver.py +25 -34
- sqlspec/adapters/asyncpg/__init__.py +5 -5
- sqlspec/adapters/asyncpg/config.py +17 -19
- sqlspec/adapters/asyncpg/driver.py +249 -93
- sqlspec/adapters/duckdb/__init__.py +2 -2
- sqlspec/adapters/duckdb/config.py +2 -2
- sqlspec/adapters/duckdb/driver.py +49 -49
- 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 +114 -41
- sqlspec/adapters/psqlpy/__init__.py +0 -0
- sqlspec/adapters/psqlpy/config.py +258 -0
- sqlspec/adapters/psqlpy/driver.py +335 -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 +180 -218
- sqlspec/adapters/sqlite/__init__.py +2 -2
- sqlspec/adapters/sqlite/config.py +2 -2
- sqlspec/adapters/sqlite/driver.py +43 -41
- sqlspec/base.py +275 -153
- sqlspec/exceptions.py +30 -0
- sqlspec/extensions/litestar/config.py +6 -0
- sqlspec/extensions/litestar/handlers.py +25 -0
- sqlspec/extensions/litestar/plugin.py +6 -1
- sqlspec/statement.py +373 -0
- sqlspec/typing.py +10 -1
- {sqlspec-0.8.0.dist-info → sqlspec-0.9.0.dist-info}/METADATA +4 -1
- sqlspec-0.9.0.dist-info/RECORD +61 -0
- sqlspec-0.8.0.dist-info/RECORD +0 -57
- {sqlspec-0.8.0.dist-info → sqlspec-0.9.0.dist-info}/WHEEL +0 -0
- {sqlspec-0.8.0.dist-info → sqlspec-0.9.0.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.8.0.dist-info → sqlspec-0.9.0.dist-info}/licenses/NOTICE +0 -0
|
@@ -17,6 +17,7 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
17
17
|
"""SQLite Async Driver Adapter."""
|
|
18
18
|
|
|
19
19
|
connection: "Connection"
|
|
20
|
+
dialect: str = "sqlite"
|
|
20
21
|
|
|
21
22
|
def __init__(self, connection: "Connection") -> None:
|
|
22
23
|
self.connection = connection
|
|
@@ -33,42 +34,15 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
33
34
|
finally:
|
|
34
35
|
await cursor.close()
|
|
35
36
|
|
|
36
|
-
def _process_sql_params(
|
|
37
|
-
self, sql: str, parameters: "Optional[StatementParameterType]" = None
|
|
38
|
-
) -> "tuple[str, Optional[Union[tuple[Any, ...], list[Any], dict[str, Any]]]]":
|
|
39
|
-
"""Process SQL query and parameters for DB-API execution.
|
|
40
|
-
|
|
41
|
-
Converts named parameters (:name) to positional parameters (?) for SQLite.
|
|
42
|
-
|
|
43
|
-
Args:
|
|
44
|
-
sql: The SQL query string.
|
|
45
|
-
parameters: The parameters for the query (dict, tuple, list, or None).
|
|
46
|
-
|
|
47
|
-
Returns:
|
|
48
|
-
A tuple containing the processed SQL string and the processed parameters.
|
|
49
|
-
"""
|
|
50
|
-
if not isinstance(parameters, dict) or not parameters:
|
|
51
|
-
# If parameters are not a dict, or empty dict, assume positional/no params
|
|
52
|
-
# Let the underlying driver handle tuples/lists directly
|
|
53
|
-
return sql, parameters
|
|
54
|
-
|
|
55
|
-
# Convert named parameters to positional parameters
|
|
56
|
-
processed_sql = sql
|
|
57
|
-
processed_params: list[Any] = []
|
|
58
|
-
for key, value in parameters.items():
|
|
59
|
-
# Replace :key with ? in the SQL
|
|
60
|
-
processed_sql = processed_sql.replace(f":{key}", "?")
|
|
61
|
-
processed_params.append(value)
|
|
62
|
-
|
|
63
|
-
return processed_sql, tuple(processed_params)
|
|
64
|
-
|
|
65
37
|
async def select(
|
|
66
38
|
self,
|
|
67
39
|
sql: str,
|
|
68
40
|
parameters: Optional["StatementParameterType"] = None,
|
|
69
41
|
/,
|
|
42
|
+
*,
|
|
70
43
|
connection: Optional["Connection"] = None,
|
|
71
44
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
45
|
+
**kwargs: Any,
|
|
72
46
|
) -> "list[Union[ModelDTOT, dict[str, Any]]]":
|
|
73
47
|
"""Fetch data from the database.
|
|
74
48
|
|
|
@@ -76,7 +50,7 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
76
50
|
List of row data as either model instances or dictionaries.
|
|
77
51
|
"""
|
|
78
52
|
connection = self._connection(connection)
|
|
79
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
53
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
80
54
|
async with self._with_cursor(connection) as cursor:
|
|
81
55
|
await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
|
|
82
56
|
results = await cursor.fetchall() # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
|
|
@@ -92,8 +66,10 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
92
66
|
sql: str,
|
|
93
67
|
parameters: Optional["StatementParameterType"] = None,
|
|
94
68
|
/,
|
|
69
|
+
*,
|
|
95
70
|
connection: Optional["Connection"] = None,
|
|
96
71
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
72
|
+
**kwargs: Any,
|
|
97
73
|
) -> "Union[ModelDTOT, dict[str, Any]]":
|
|
98
74
|
"""Fetch one row from the database.
|
|
99
75
|
|
|
@@ -101,7 +77,7 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
101
77
|
The first row of the query results.
|
|
102
78
|
"""
|
|
103
79
|
connection = self._connection(connection)
|
|
104
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
80
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
105
81
|
async with self._with_cursor(connection) as cursor:
|
|
106
82
|
await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
|
|
107
83
|
result = await cursor.fetchone() # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
|
|
@@ -116,8 +92,10 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
116
92
|
sql: str,
|
|
117
93
|
parameters: Optional["StatementParameterType"] = None,
|
|
118
94
|
/,
|
|
95
|
+
*,
|
|
119
96
|
connection: Optional["Connection"] = None,
|
|
120
97
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
98
|
+
**kwargs: Any,
|
|
121
99
|
) -> "Optional[Union[ModelDTOT, dict[str, Any]]]":
|
|
122
100
|
"""Fetch one row from the database.
|
|
123
101
|
|
|
@@ -125,7 +103,7 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
125
103
|
The first row of the query results.
|
|
126
104
|
"""
|
|
127
105
|
connection = self._connection(connection)
|
|
128
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
106
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
129
107
|
async with self._with_cursor(connection) as cursor:
|
|
130
108
|
await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
|
|
131
109
|
result = await cursor.fetchone() # pyright: ignore[reportUnknownMemberType, reportUnknownVariableType]
|
|
@@ -141,8 +119,10 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
141
119
|
sql: str,
|
|
142
120
|
parameters: "Optional[StatementParameterType]" = None,
|
|
143
121
|
/,
|
|
122
|
+
*,
|
|
144
123
|
connection: "Optional[Connection]" = None,
|
|
145
124
|
schema_type: "Optional[type[T]]" = None,
|
|
125
|
+
**kwargs: Any,
|
|
146
126
|
) -> "Union[T, Any]":
|
|
147
127
|
"""Fetch a single value from the database.
|
|
148
128
|
|
|
@@ -150,7 +130,7 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
150
130
|
The first value from the first row of results, or None if no results.
|
|
151
131
|
"""
|
|
152
132
|
connection = self._connection(connection)
|
|
153
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
133
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
154
134
|
async with self._with_cursor(connection) as cursor:
|
|
155
135
|
await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
|
|
156
136
|
result = await cursor.fetchone() # pyright: ignore[reportUnknownMemberType]
|
|
@@ -164,8 +144,10 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
164
144
|
sql: str,
|
|
165
145
|
parameters: "Optional[StatementParameterType]" = None,
|
|
166
146
|
/,
|
|
147
|
+
*,
|
|
167
148
|
connection: "Optional[Connection]" = None,
|
|
168
149
|
schema_type: "Optional[type[T]]" = None,
|
|
150
|
+
**kwargs: Any,
|
|
169
151
|
) -> "Optional[Union[T, Any]]":
|
|
170
152
|
"""Fetch a single value from the database.
|
|
171
153
|
|
|
@@ -173,8 +155,7 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
173
155
|
The first value from the first row of results, or None if no results.
|
|
174
156
|
"""
|
|
175
157
|
connection = self._connection(connection)
|
|
176
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
177
|
-
|
|
158
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
178
159
|
async with self._with_cursor(connection) as cursor:
|
|
179
160
|
await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
|
|
180
161
|
result = await cursor.fetchone() # pyright: ignore[reportUnknownMemberType]
|
|
@@ -189,7 +170,9 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
189
170
|
sql: str,
|
|
190
171
|
parameters: Optional["StatementParameterType"] = None,
|
|
191
172
|
/,
|
|
173
|
+
*,
|
|
192
174
|
connection: Optional["Connection"] = None,
|
|
175
|
+
**kwargs: Any,
|
|
193
176
|
) -> int:
|
|
194
177
|
"""Insert, update, or delete data from the database.
|
|
195
178
|
|
|
@@ -197,7 +180,7 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
197
180
|
Row count affected by the operation.
|
|
198
181
|
"""
|
|
199
182
|
connection = self._connection(connection)
|
|
200
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
183
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
201
184
|
|
|
202
185
|
async with self._with_cursor(connection) as cursor:
|
|
203
186
|
await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
|
|
@@ -208,8 +191,10 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
208
191
|
sql: str,
|
|
209
192
|
parameters: Optional["StatementParameterType"] = None,
|
|
210
193
|
/,
|
|
194
|
+
*,
|
|
211
195
|
connection: Optional["Connection"] = None,
|
|
212
196
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
197
|
+
**kwargs: Any,
|
|
213
198
|
) -> "Optional[Union[dict[str, Any], ModelDTOT]]":
|
|
214
199
|
"""Insert, update, or delete data from the database and return result.
|
|
215
200
|
|
|
@@ -217,7 +202,7 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
217
202
|
The first row of results.
|
|
218
203
|
"""
|
|
219
204
|
connection = self._connection(connection)
|
|
220
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
205
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
221
206
|
|
|
222
207
|
async with self._with_cursor(connection) as cursor:
|
|
223
208
|
await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
|
|
@@ -234,7 +219,9 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
234
219
|
sql: str,
|
|
235
220
|
parameters: Optional["StatementParameterType"] = None,
|
|
236
221
|
/,
|
|
222
|
+
*,
|
|
237
223
|
connection: Optional["Connection"] = None,
|
|
224
|
+
**kwargs: Any,
|
|
238
225
|
) -> str:
|
|
239
226
|
"""Execute a script.
|
|
240
227
|
|
|
@@ -242,7 +229,7 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
242
229
|
Status message for the operation.
|
|
243
230
|
"""
|
|
244
231
|
connection = self._connection(connection)
|
|
245
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
232
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
246
233
|
|
|
247
234
|
async with self._with_cursor(connection) as cursor:
|
|
248
235
|
await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
|
|
@@ -253,8 +240,10 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
253
240
|
sql: str,
|
|
254
241
|
parameters: Optional["StatementParameterType"] = None,
|
|
255
242
|
/,
|
|
243
|
+
*,
|
|
256
244
|
connection: Optional["Connection"] = None,
|
|
257
245
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
246
|
+
**kwargs: Any,
|
|
258
247
|
) -> "Optional[Union[dict[str, Any], ModelDTOT]]":
|
|
259
248
|
"""Execute a script and return result.
|
|
260
249
|
|
|
@@ -262,7 +251,7 @@ class AiosqliteDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
262
251
|
The first row of results.
|
|
263
252
|
"""
|
|
264
253
|
connection = self._connection(connection)
|
|
265
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
254
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
266
255
|
|
|
267
256
|
async with self._with_cursor(connection) as cursor:
|
|
268
257
|
await cursor.execute(sql, parameters) # pyright: ignore[reportUnknownMemberType]
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
from sqlspec.adapters.asyncmy.config import
|
|
1
|
+
from sqlspec.adapters.asyncmy.config import AsyncmyConfig, AsyncmyPoolConfig
|
|
2
2
|
from sqlspec.adapters.asyncmy.driver import AsyncmyDriver # type: ignore[attr-defined]
|
|
3
3
|
|
|
4
4
|
__all__ = (
|
|
5
|
-
"
|
|
5
|
+
"AsyncmyConfig",
|
|
6
6
|
"AsyncmyDriver",
|
|
7
|
-
"
|
|
7
|
+
"AsyncmyPoolConfig",
|
|
8
8
|
)
|
|
@@ -16,8 +16,8 @@ if TYPE_CHECKING:
|
|
|
16
16
|
from asyncmy.pool import Pool # pyright: ignore[reportUnknownVariableType]
|
|
17
17
|
|
|
18
18
|
__all__ = (
|
|
19
|
-
"
|
|
20
|
-
"
|
|
19
|
+
"AsyncmyConfig",
|
|
20
|
+
"AsyncmyPoolConfig",
|
|
21
21
|
)
|
|
22
22
|
|
|
23
23
|
|
|
@@ -25,7 +25,7 @@ T = TypeVar("T")
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
@dataclass
|
|
28
|
-
class
|
|
28
|
+
class AsyncmyPoolConfig(GenericPoolConfig):
|
|
29
29
|
"""Configuration for Asyncmy's connection pool.
|
|
30
30
|
|
|
31
31
|
This class provides configuration options for Asyncmy database connection pools.
|
|
@@ -104,19 +104,19 @@ class AsyncmyPool(GenericPoolConfig):
|
|
|
104
104
|
|
|
105
105
|
|
|
106
106
|
@dataclass
|
|
107
|
-
class
|
|
107
|
+
class AsyncmyConfig(AsyncDatabaseConfig["Connection", "Pool", "AsyncmyDriver"]):
|
|
108
108
|
"""Asyncmy Configuration."""
|
|
109
109
|
|
|
110
110
|
__is_async__ = True
|
|
111
111
|
__supports_connection_pooling__ = True
|
|
112
112
|
|
|
113
|
-
pool_config: "Optional[
|
|
113
|
+
pool_config: "Optional[AsyncmyPoolConfig]" = None
|
|
114
114
|
"""Asyncmy Pool configuration"""
|
|
115
|
-
connection_type: "type[Connection]" = field(init=False, default_factory=lambda: Connection) # pyright: ignore
|
|
115
|
+
connection_type: "type[Connection]" = field(hash=False, init=False, default_factory=lambda: Connection) # pyright: ignore
|
|
116
116
|
"""Type of the connection object"""
|
|
117
|
-
driver_type: "type[AsyncmyDriver]" = field(init=False, default_factory=lambda: AsyncmyDriver)
|
|
117
|
+
driver_type: "type[AsyncmyDriver]" = field(hash=False, init=False, default_factory=lambda: AsyncmyDriver)
|
|
118
118
|
"""Type of the driver object"""
|
|
119
|
-
pool_instance: "Optional[Pool]" = None # pyright: ignore[reportUnknownVariableType]
|
|
119
|
+
pool_instance: "Optional[Pool]" = field(hash=False, default=None) # pyright: ignore[reportUnknownVariableType]
|
|
120
120
|
"""Instance of the pool"""
|
|
121
121
|
|
|
122
122
|
@property
|
|
@@ -162,7 +162,7 @@ class Asyncmy(AsyncDatabaseConfig["Connection", "Pool", "AsyncmyDriver"]):
|
|
|
162
162
|
raise ImproperConfigurationError(msg)
|
|
163
163
|
|
|
164
164
|
async def create_connection(self) -> "Connection": # pyright: ignore[reportUnknownParameterType]
|
|
165
|
-
"""Create and return a new asyncmy connection.
|
|
165
|
+
"""Create and return a new asyncmy connection from the pool.
|
|
166
166
|
|
|
167
167
|
Returns:
|
|
168
168
|
A Connection instance.
|
|
@@ -171,9 +171,8 @@ class Asyncmy(AsyncDatabaseConfig["Connection", "Pool", "AsyncmyDriver"]):
|
|
|
171
171
|
ImproperConfigurationError: If the connection could not be created.
|
|
172
172
|
"""
|
|
173
173
|
try:
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
return await asyncmy.connect(**self.connection_config_dict) # pyright: ignore
|
|
174
|
+
async with self.provide_connection() as conn:
|
|
175
|
+
return conn
|
|
177
176
|
except Exception as e:
|
|
178
177
|
msg = f"Could not configure the Asyncmy connection. Error: {e!s}"
|
|
179
178
|
raise ImproperConfigurationError(msg) from e
|
|
@@ -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
|
|
@@ -40,8 +41,10 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
40
41
|
sql: str,
|
|
41
42
|
parameters: Optional["StatementParameterType"] = None,
|
|
42
43
|
/,
|
|
44
|
+
*,
|
|
43
45
|
connection: Optional["Connection"] = None,
|
|
44
46
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
47
|
+
**kwargs: Any,
|
|
45
48
|
) -> "list[Union[ModelDTOT, dict[str, Any]]]":
|
|
46
49
|
"""Fetch data from the database.
|
|
47
50
|
|
|
@@ -49,7 +52,7 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
49
52
|
List of row data as either model instances or dictionaries.
|
|
50
53
|
"""
|
|
51
54
|
connection = self._connection(connection)
|
|
52
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
55
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
53
56
|
async with self._with_cursor(connection) as cursor:
|
|
54
57
|
await cursor.execute(sql, parameters)
|
|
55
58
|
results = await cursor.fetchall()
|
|
@@ -65,8 +68,10 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
65
68
|
sql: str,
|
|
66
69
|
parameters: Optional["StatementParameterType"] = None,
|
|
67
70
|
/,
|
|
71
|
+
*,
|
|
68
72
|
connection: Optional["Connection"] = None,
|
|
69
73
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
74
|
+
**kwargs: Any,
|
|
70
75
|
) -> "Union[ModelDTOT, dict[str, Any]]":
|
|
71
76
|
"""Fetch one row from the database.
|
|
72
77
|
|
|
@@ -74,7 +79,7 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
74
79
|
The first row of the query results.
|
|
75
80
|
"""
|
|
76
81
|
connection = self._connection(connection)
|
|
77
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
82
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
78
83
|
async with self._with_cursor(connection) as cursor:
|
|
79
84
|
await cursor.execute(sql, parameters)
|
|
80
85
|
result = await cursor.fetchone()
|
|
@@ -89,8 +94,10 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
89
94
|
sql: str,
|
|
90
95
|
parameters: Optional["StatementParameterType"] = None,
|
|
91
96
|
/,
|
|
97
|
+
*,
|
|
92
98
|
connection: Optional["Connection"] = None,
|
|
93
99
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
100
|
+
**kwargs: Any,
|
|
94
101
|
) -> "Optional[Union[ModelDTOT, dict[str, Any]]]":
|
|
95
102
|
"""Fetch one row from the database.
|
|
96
103
|
|
|
@@ -98,7 +105,7 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
98
105
|
The first row of the query results.
|
|
99
106
|
"""
|
|
100
107
|
connection = self._connection(connection)
|
|
101
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
108
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
102
109
|
async with self._with_cursor(connection) as cursor:
|
|
103
110
|
await cursor.execute(sql, parameters)
|
|
104
111
|
result = await cursor.fetchone()
|
|
@@ -114,8 +121,10 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
114
121
|
sql: str,
|
|
115
122
|
parameters: "Optional[StatementParameterType]" = None,
|
|
116
123
|
/,
|
|
124
|
+
*,
|
|
117
125
|
connection: "Optional[Connection]" = None,
|
|
118
126
|
schema_type: "Optional[type[T]]" = None,
|
|
127
|
+
**kwargs: Any,
|
|
119
128
|
) -> "Union[T, Any]":
|
|
120
129
|
"""Fetch a single value from the database.
|
|
121
130
|
|
|
@@ -123,7 +132,7 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
123
132
|
The first value from the first row of results, or None if no results.
|
|
124
133
|
"""
|
|
125
134
|
connection = self._connection(connection)
|
|
126
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
135
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
127
136
|
|
|
128
137
|
async with self._with_cursor(connection) as cursor:
|
|
129
138
|
await cursor.execute(sql, parameters)
|
|
@@ -140,8 +149,10 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
140
149
|
sql: str,
|
|
141
150
|
parameters: "Optional[StatementParameterType]" = None,
|
|
142
151
|
/,
|
|
152
|
+
*,
|
|
143
153
|
connection: "Optional[Connection]" = None,
|
|
144
154
|
schema_type: "Optional[type[T]]" = None,
|
|
155
|
+
**kwargs: Any,
|
|
145
156
|
) -> "Optional[Union[T, Any]]":
|
|
146
157
|
"""Fetch a single value from the database.
|
|
147
158
|
|
|
@@ -149,7 +160,7 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
149
160
|
The first value from the first row of results, or None if no results.
|
|
150
161
|
"""
|
|
151
162
|
connection = self._connection(connection)
|
|
152
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
163
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
153
164
|
|
|
154
165
|
async with self._with_cursor(connection) as cursor:
|
|
155
166
|
await cursor.execute(sql, parameters)
|
|
@@ -168,7 +179,9 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
168
179
|
sql: str,
|
|
169
180
|
parameters: Optional["StatementParameterType"] = None,
|
|
170
181
|
/,
|
|
182
|
+
*,
|
|
171
183
|
connection: Optional["Connection"] = None,
|
|
184
|
+
**kwargs: Any,
|
|
172
185
|
) -> int:
|
|
173
186
|
"""Insert, update, or delete data from the database.
|
|
174
187
|
|
|
@@ -176,7 +189,7 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
176
189
|
Row count affected by the operation.
|
|
177
190
|
"""
|
|
178
191
|
connection = self._connection(connection)
|
|
179
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
192
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
180
193
|
|
|
181
194
|
async with self._with_cursor(connection) as cursor:
|
|
182
195
|
await cursor.execute(sql, parameters)
|
|
@@ -187,8 +200,10 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
187
200
|
sql: str,
|
|
188
201
|
parameters: Optional["StatementParameterType"] = None,
|
|
189
202
|
/,
|
|
203
|
+
*,
|
|
190
204
|
connection: Optional["Connection"] = None,
|
|
191
205
|
schema_type: "Optional[type[ModelDTOT]]" = None,
|
|
206
|
+
**kwargs: Any,
|
|
192
207
|
) -> "Optional[Union[dict[str, Any], ModelDTOT]]":
|
|
193
208
|
"""Insert, update, or delete data from the database and return result.
|
|
194
209
|
|
|
@@ -196,7 +211,7 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
196
211
|
The first row of results.
|
|
197
212
|
"""
|
|
198
213
|
connection = self._connection(connection)
|
|
199
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
214
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
200
215
|
column_names: list[str] = []
|
|
201
216
|
|
|
202
217
|
async with self._with_cursor(connection) as cursor:
|
|
@@ -214,7 +229,9 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
214
229
|
sql: str,
|
|
215
230
|
parameters: Optional["StatementParameterType"] = None,
|
|
216
231
|
/,
|
|
232
|
+
*,
|
|
217
233
|
connection: Optional["Connection"] = None,
|
|
234
|
+
**kwargs: Any,
|
|
218
235
|
) -> str:
|
|
219
236
|
"""Execute a script.
|
|
220
237
|
|
|
@@ -222,34 +239,8 @@ class AsyncmyDriver(AsyncDriverAdapterProtocol["Connection"]):
|
|
|
222
239
|
Status message for the operation.
|
|
223
240
|
"""
|
|
224
241
|
connection = self._connection(connection)
|
|
225
|
-
sql, parameters = self._process_sql_params(sql, parameters)
|
|
242
|
+
sql, parameters = self._process_sql_params(sql, parameters, **kwargs)
|
|
226
243
|
|
|
227
244
|
async with self._with_cursor(connection) as cursor:
|
|
228
245
|
await cursor.execute(sql, parameters)
|
|
229
246
|
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
|