sqlspec 0.11.0__py3-none-any.whl → 0.12.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/__init__.py +16 -3
- sqlspec/_serialization.py +3 -10
- sqlspec/_sql.py +1147 -0
- sqlspec/_typing.py +343 -41
- sqlspec/adapters/adbc/__init__.py +2 -6
- sqlspec/adapters/adbc/config.py +474 -149
- sqlspec/adapters/adbc/driver.py +330 -644
- sqlspec/adapters/aiosqlite/__init__.py +2 -6
- sqlspec/adapters/aiosqlite/config.py +143 -57
- sqlspec/adapters/aiosqlite/driver.py +269 -462
- sqlspec/adapters/asyncmy/__init__.py +3 -8
- sqlspec/adapters/asyncmy/config.py +247 -202
- sqlspec/adapters/asyncmy/driver.py +217 -451
- sqlspec/adapters/asyncpg/__init__.py +4 -7
- sqlspec/adapters/asyncpg/config.py +329 -176
- sqlspec/adapters/asyncpg/driver.py +418 -498
- sqlspec/adapters/bigquery/__init__.py +2 -2
- sqlspec/adapters/bigquery/config.py +407 -0
- sqlspec/adapters/bigquery/driver.py +592 -634
- sqlspec/adapters/duckdb/__init__.py +4 -1
- sqlspec/adapters/duckdb/config.py +432 -321
- sqlspec/adapters/duckdb/driver.py +393 -436
- sqlspec/adapters/oracledb/__init__.py +3 -8
- sqlspec/adapters/oracledb/config.py +625 -0
- sqlspec/adapters/oracledb/driver.py +549 -942
- sqlspec/adapters/psqlpy/__init__.py +4 -7
- sqlspec/adapters/psqlpy/config.py +372 -203
- sqlspec/adapters/psqlpy/driver.py +197 -550
- sqlspec/adapters/psycopg/__init__.py +3 -8
- sqlspec/adapters/psycopg/config.py +741 -0
- sqlspec/adapters/psycopg/driver.py +732 -733
- sqlspec/adapters/sqlite/__init__.py +2 -6
- sqlspec/adapters/sqlite/config.py +146 -81
- sqlspec/adapters/sqlite/driver.py +243 -426
- sqlspec/base.py +220 -825
- sqlspec/config.py +354 -0
- sqlspec/driver/__init__.py +22 -0
- sqlspec/driver/_async.py +252 -0
- sqlspec/driver/_common.py +338 -0
- sqlspec/driver/_sync.py +261 -0
- sqlspec/driver/mixins/__init__.py +17 -0
- sqlspec/driver/mixins/_pipeline.py +523 -0
- sqlspec/driver/mixins/_result_utils.py +122 -0
- sqlspec/driver/mixins/_sql_translator.py +35 -0
- sqlspec/driver/mixins/_storage.py +993 -0
- sqlspec/driver/mixins/_type_coercion.py +131 -0
- sqlspec/exceptions.py +299 -7
- sqlspec/extensions/aiosql/__init__.py +10 -0
- sqlspec/extensions/aiosql/adapter.py +474 -0
- sqlspec/extensions/litestar/__init__.py +1 -6
- sqlspec/extensions/litestar/_utils.py +1 -5
- sqlspec/extensions/litestar/config.py +5 -6
- sqlspec/extensions/litestar/handlers.py +13 -12
- sqlspec/extensions/litestar/plugin.py +22 -24
- sqlspec/extensions/litestar/providers.py +37 -55
- sqlspec/loader.py +528 -0
- sqlspec/service/__init__.py +3 -0
- sqlspec/service/base.py +24 -0
- sqlspec/service/pagination.py +26 -0
- sqlspec/statement/__init__.py +21 -0
- sqlspec/statement/builder/__init__.py +54 -0
- sqlspec/statement/builder/_ddl_utils.py +119 -0
- sqlspec/statement/builder/_parsing_utils.py +135 -0
- sqlspec/statement/builder/base.py +328 -0
- sqlspec/statement/builder/ddl.py +1379 -0
- sqlspec/statement/builder/delete.py +80 -0
- sqlspec/statement/builder/insert.py +274 -0
- sqlspec/statement/builder/merge.py +95 -0
- sqlspec/statement/builder/mixins/__init__.py +65 -0
- sqlspec/statement/builder/mixins/_aggregate_functions.py +151 -0
- sqlspec/statement/builder/mixins/_case_builder.py +91 -0
- sqlspec/statement/builder/mixins/_common_table_expr.py +91 -0
- sqlspec/statement/builder/mixins/_delete_from.py +34 -0
- sqlspec/statement/builder/mixins/_from.py +61 -0
- sqlspec/statement/builder/mixins/_group_by.py +119 -0
- sqlspec/statement/builder/mixins/_having.py +35 -0
- sqlspec/statement/builder/mixins/_insert_from_select.py +48 -0
- sqlspec/statement/builder/mixins/_insert_into.py +36 -0
- sqlspec/statement/builder/mixins/_insert_values.py +69 -0
- sqlspec/statement/builder/mixins/_join.py +110 -0
- sqlspec/statement/builder/mixins/_limit_offset.py +53 -0
- sqlspec/statement/builder/mixins/_merge_clauses.py +405 -0
- sqlspec/statement/builder/mixins/_order_by.py +46 -0
- sqlspec/statement/builder/mixins/_pivot.py +82 -0
- sqlspec/statement/builder/mixins/_returning.py +37 -0
- sqlspec/statement/builder/mixins/_select_columns.py +60 -0
- sqlspec/statement/builder/mixins/_set_ops.py +122 -0
- sqlspec/statement/builder/mixins/_unpivot.py +80 -0
- sqlspec/statement/builder/mixins/_update_from.py +54 -0
- sqlspec/statement/builder/mixins/_update_set.py +91 -0
- sqlspec/statement/builder/mixins/_update_table.py +29 -0
- sqlspec/statement/builder/mixins/_where.py +374 -0
- sqlspec/statement/builder/mixins/_window_functions.py +86 -0
- sqlspec/statement/builder/protocols.py +20 -0
- sqlspec/statement/builder/select.py +206 -0
- sqlspec/statement/builder/update.py +178 -0
- sqlspec/statement/filters.py +571 -0
- sqlspec/statement/parameters.py +736 -0
- sqlspec/statement/pipelines/__init__.py +67 -0
- sqlspec/statement/pipelines/analyzers/__init__.py +9 -0
- sqlspec/statement/pipelines/analyzers/_analyzer.py +649 -0
- sqlspec/statement/pipelines/base.py +315 -0
- sqlspec/statement/pipelines/context.py +119 -0
- sqlspec/statement/pipelines/result_types.py +41 -0
- sqlspec/statement/pipelines/transformers/__init__.py +8 -0
- sqlspec/statement/pipelines/transformers/_expression_simplifier.py +256 -0
- sqlspec/statement/pipelines/transformers/_literal_parameterizer.py +623 -0
- sqlspec/statement/pipelines/transformers/_remove_comments.py +66 -0
- sqlspec/statement/pipelines/transformers/_remove_hints.py +81 -0
- sqlspec/statement/pipelines/validators/__init__.py +23 -0
- sqlspec/statement/pipelines/validators/_dml_safety.py +275 -0
- sqlspec/statement/pipelines/validators/_parameter_style.py +297 -0
- sqlspec/statement/pipelines/validators/_performance.py +703 -0
- sqlspec/statement/pipelines/validators/_security.py +990 -0
- sqlspec/statement/pipelines/validators/base.py +67 -0
- sqlspec/statement/result.py +527 -0
- sqlspec/statement/splitter.py +701 -0
- sqlspec/statement/sql.py +1198 -0
- sqlspec/storage/__init__.py +15 -0
- sqlspec/storage/backends/__init__.py +0 -0
- sqlspec/storage/backends/base.py +166 -0
- sqlspec/storage/backends/fsspec.py +315 -0
- sqlspec/storage/backends/obstore.py +464 -0
- sqlspec/storage/protocol.py +170 -0
- sqlspec/storage/registry.py +315 -0
- sqlspec/typing.py +157 -36
- sqlspec/utils/correlation.py +155 -0
- sqlspec/utils/deprecation.py +3 -6
- sqlspec/utils/fixtures.py +6 -11
- sqlspec/utils/logging.py +135 -0
- sqlspec/utils/module_loader.py +45 -43
- sqlspec/utils/serializers.py +4 -0
- sqlspec/utils/singleton.py +6 -8
- sqlspec/utils/sync_tools.py +15 -27
- sqlspec/utils/text.py +58 -26
- {sqlspec-0.11.0.dist-info → sqlspec-0.12.0.dist-info}/METADATA +100 -26
- sqlspec-0.12.0.dist-info/RECORD +145 -0
- sqlspec/adapters/bigquery/config/__init__.py +0 -3
- sqlspec/adapters/bigquery/config/_common.py +0 -40
- sqlspec/adapters/bigquery/config/_sync.py +0 -87
- sqlspec/adapters/oracledb/config/__init__.py +0 -9
- sqlspec/adapters/oracledb/config/_asyncio.py +0 -186
- sqlspec/adapters/oracledb/config/_common.py +0 -131
- sqlspec/adapters/oracledb/config/_sync.py +0 -186
- sqlspec/adapters/psycopg/config/__init__.py +0 -19
- sqlspec/adapters/psycopg/config/_async.py +0 -169
- sqlspec/adapters/psycopg/config/_common.py +0 -56
- sqlspec/adapters/psycopg/config/_sync.py +0 -168
- sqlspec/filters.py +0 -330
- sqlspec/mixins.py +0 -306
- sqlspec/statement.py +0 -378
- sqlspec-0.11.0.dist-info/RECORD +0 -69
- {sqlspec-0.11.0.dist-info → sqlspec-0.12.0.dist-info}/WHEEL +0 -0
- {sqlspec-0.11.0.dist-info → sqlspec-0.12.0.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.11.0.dist-info → sqlspec-0.12.0.dist-info}/licenses/NOTICE +0 -0
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
from sqlspec.adapters.asyncmy.config import
|
|
2
|
-
from sqlspec.adapters.asyncmy.driver import AsyncmyConnection, AsyncmyDriver
|
|
1
|
+
from sqlspec.adapters.asyncmy.config import CONNECTION_FIELDS, POOL_FIELDS, AsyncmyConfig
|
|
2
|
+
from sqlspec.adapters.asyncmy.driver import AsyncmyConnection, AsyncmyDriver
|
|
3
3
|
|
|
4
|
-
__all__ = (
|
|
5
|
-
"AsyncmyConfig",
|
|
6
|
-
"AsyncmyConnection",
|
|
7
|
-
"AsyncmyDriver",
|
|
8
|
-
"AsyncmyPoolConfig",
|
|
9
|
-
)
|
|
4
|
+
__all__ = ("CONNECTION_FIELDS", "POOL_FIELDS", "AsyncmyConfig", "AsyncmyConnection", "AsyncmyDriver")
|
|
@@ -1,241 +1,286 @@
|
|
|
1
|
+
"""Asyncmy database configuration with direct field-based configuration."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from collections.abc import AsyncGenerator
|
|
1
5
|
from contextlib import asynccontextmanager
|
|
2
|
-
from dataclasses import
|
|
3
|
-
from typing import TYPE_CHECKING, Any,
|
|
6
|
+
from dataclasses import replace
|
|
7
|
+
from typing import TYPE_CHECKING, Any, ClassVar, Optional, Union
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
import asyncmy
|
|
6
10
|
|
|
7
|
-
from sqlspec.adapters.asyncmy.driver import AsyncmyDriver
|
|
8
|
-
from sqlspec.
|
|
9
|
-
from sqlspec.
|
|
10
|
-
from sqlspec.typing import
|
|
11
|
+
from sqlspec.adapters.asyncmy.driver import AsyncmyConnection, AsyncmyDriver
|
|
12
|
+
from sqlspec.config import AsyncDatabaseConfig
|
|
13
|
+
from sqlspec.statement.sql import SQLConfig
|
|
14
|
+
from sqlspec.typing import DictRow, Empty
|
|
11
15
|
|
|
12
16
|
if TYPE_CHECKING:
|
|
13
|
-
from
|
|
14
|
-
|
|
15
|
-
from
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
__all__ = (
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
from asyncmy.cursors import Cursor, DictCursor
|
|
18
|
+
from asyncmy.pool import Pool
|
|
19
|
+
from sqlglot.dialects.dialect import DialectType
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
__all__ = ("CONNECTION_FIELDS", "POOL_FIELDS", "AsyncmyConfig")
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
CONNECTION_FIELDS = frozenset(
|
|
27
|
+
{
|
|
28
|
+
"host",
|
|
29
|
+
"user",
|
|
30
|
+
"password",
|
|
31
|
+
"database",
|
|
32
|
+
"port",
|
|
33
|
+
"unix_socket",
|
|
34
|
+
"charset",
|
|
35
|
+
"connect_timeout",
|
|
36
|
+
"read_default_file",
|
|
37
|
+
"read_default_group",
|
|
38
|
+
"autocommit",
|
|
39
|
+
"local_infile",
|
|
40
|
+
"ssl",
|
|
41
|
+
"sql_mode",
|
|
42
|
+
"init_command",
|
|
43
|
+
"cursor_class",
|
|
44
|
+
}
|
|
21
45
|
)
|
|
22
46
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
"""
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"""
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
47
|
+
POOL_FIELDS = CONNECTION_FIELDS.union({"minsize", "maxsize", "echo", "pool_recycle"})
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class AsyncmyConfig(AsyncDatabaseConfig[AsyncmyConnection, "Pool", AsyncmyDriver]): # pyright: ignore
|
|
51
|
+
"""Configuration for Asyncmy database connections with direct field-based configuration."""
|
|
52
|
+
|
|
53
|
+
__slots__ = (
|
|
54
|
+
"_dialect",
|
|
55
|
+
"autocommit",
|
|
56
|
+
"charset",
|
|
57
|
+
"connect_timeout",
|
|
58
|
+
"cursor_class",
|
|
59
|
+
"database",
|
|
60
|
+
"default_row_type",
|
|
61
|
+
"echo",
|
|
62
|
+
"extras",
|
|
63
|
+
"host",
|
|
64
|
+
"init_command",
|
|
65
|
+
"local_infile",
|
|
66
|
+
"maxsize",
|
|
67
|
+
"minsize",
|
|
68
|
+
"password",
|
|
69
|
+
"pool_instance",
|
|
70
|
+
"pool_recycle",
|
|
71
|
+
"port",
|
|
72
|
+
"read_default_file",
|
|
73
|
+
"read_default_group",
|
|
74
|
+
"sql_mode",
|
|
75
|
+
"ssl",
|
|
76
|
+
"statement_config",
|
|
77
|
+
"unix_socket",
|
|
78
|
+
"user",
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
is_async: ClassVar[bool] = True
|
|
82
|
+
supports_connection_pooling: ClassVar[bool] = True
|
|
83
|
+
driver_type: type[AsyncmyDriver] = AsyncmyDriver
|
|
84
|
+
connection_type: type[AsyncmyConnection] = AsyncmyConnection # pyright: ignore
|
|
85
|
+
|
|
86
|
+
# Parameter style support information
|
|
87
|
+
supported_parameter_styles: ClassVar[tuple[str, ...]] = ("pyformat_positional",)
|
|
88
|
+
"""AsyncMy only supports %s (pyformat_positional) parameter style."""
|
|
89
|
+
|
|
90
|
+
preferred_parameter_style: ClassVar[str] = "pyformat_positional"
|
|
91
|
+
"""AsyncMy's native parameter style is %s (pyformat_positional)."""
|
|
92
|
+
|
|
93
|
+
def __init__(
|
|
94
|
+
self,
|
|
95
|
+
statement_config: Optional[SQLConfig] = None,
|
|
96
|
+
default_row_type: type[DictRow] = DictRow,
|
|
97
|
+
# Connection parameters
|
|
98
|
+
host: Optional[str] = None,
|
|
99
|
+
user: Optional[str] = None,
|
|
100
|
+
password: Optional[str] = None,
|
|
101
|
+
database: Optional[str] = None,
|
|
102
|
+
port: Optional[int] = None,
|
|
103
|
+
unix_socket: Optional[str] = None,
|
|
104
|
+
charset: Optional[str] = None,
|
|
105
|
+
connect_timeout: Optional[float] = None,
|
|
106
|
+
read_default_file: Optional[str] = None,
|
|
107
|
+
read_default_group: Optional[str] = None,
|
|
108
|
+
autocommit: Optional[bool] = None,
|
|
109
|
+
local_infile: Optional[bool] = None,
|
|
110
|
+
ssl: Optional[Any] = None,
|
|
111
|
+
sql_mode: Optional[str] = None,
|
|
112
|
+
init_command: Optional[str] = None,
|
|
113
|
+
cursor_class: Optional[Union["type[Cursor]", "type[DictCursor]"]] = None,
|
|
114
|
+
# Pool parameters
|
|
115
|
+
minsize: Optional[int] = None,
|
|
116
|
+
maxsize: Optional[int] = None,
|
|
117
|
+
echo: Optional[bool] = None,
|
|
118
|
+
pool_recycle: Optional[int] = None,
|
|
119
|
+
pool_instance: Optional["Pool"] = None,
|
|
120
|
+
**kwargs: Any,
|
|
121
|
+
) -> None:
|
|
122
|
+
"""Initialize Asyncmy configuration.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
statement_config: Default SQL statement configuration
|
|
126
|
+
default_row_type: Default row type for results
|
|
127
|
+
host: Host where the database server is located
|
|
128
|
+
user: The username used to authenticate with the database
|
|
129
|
+
password: The password used to authenticate with the database
|
|
130
|
+
database: The database name to use
|
|
131
|
+
port: The TCP/IP port of the MySQL server
|
|
132
|
+
unix_socket: The location of the Unix socket file
|
|
133
|
+
charset: The character set to use for the connection
|
|
134
|
+
connect_timeout: Timeout before throwing an error when connecting
|
|
135
|
+
read_default_file: MySQL configuration file to read
|
|
136
|
+
read_default_group: Group to read from the configuration file
|
|
137
|
+
autocommit: If True, autocommit mode will be enabled
|
|
138
|
+
local_infile: If True, enables LOAD LOCAL INFILE
|
|
139
|
+
ssl: SSL connection parameters or boolean
|
|
140
|
+
sql_mode: Default SQL_MODE to use
|
|
141
|
+
init_command: Initial SQL statement to execute once connected
|
|
142
|
+
cursor_class: Custom cursor class to use
|
|
143
|
+
minsize: Minimum number of connections to keep in the pool
|
|
144
|
+
maxsize: Maximum number of connections allowed in the pool
|
|
145
|
+
echo: If True, logging will be enabled for all SQL statements
|
|
146
|
+
pool_recycle: Number of seconds after which a connection is recycled
|
|
147
|
+
pool_instance: Existing connection pool instance to use
|
|
148
|
+
**kwargs: Additional parameters (stored in extras)
|
|
149
|
+
"""
|
|
150
|
+
# Store connection parameters as instance attributes
|
|
151
|
+
self.host = host
|
|
152
|
+
self.user = user
|
|
153
|
+
self.password = password
|
|
154
|
+
self.database = database
|
|
155
|
+
self.port = port
|
|
156
|
+
self.unix_socket = unix_socket
|
|
157
|
+
self.charset = charset
|
|
158
|
+
self.connect_timeout = connect_timeout
|
|
159
|
+
self.read_default_file = read_default_file
|
|
160
|
+
self.read_default_group = read_default_group
|
|
161
|
+
self.autocommit = autocommit
|
|
162
|
+
self.local_infile = local_infile
|
|
163
|
+
self.ssl = ssl
|
|
164
|
+
self.sql_mode = sql_mode
|
|
165
|
+
self.init_command = init_command
|
|
166
|
+
self.cursor_class = cursor_class
|
|
167
|
+
|
|
168
|
+
# Store pool parameters as instance attributes
|
|
169
|
+
self.minsize = minsize
|
|
170
|
+
self.maxsize = maxsize
|
|
171
|
+
self.echo = echo
|
|
172
|
+
self.pool_recycle = pool_recycle
|
|
173
|
+
self.extras = kwargs or {}
|
|
174
|
+
|
|
175
|
+
# Store other config
|
|
176
|
+
self.statement_config = statement_config or SQLConfig()
|
|
177
|
+
self.default_row_type = default_row_type
|
|
178
|
+
self.pool_instance: Optional[Pool] = pool_instance
|
|
179
|
+
self._dialect: DialectType = None
|
|
180
|
+
|
|
181
|
+
super().__init__() # pyright: ignore
|
|
95
182
|
|
|
96
183
|
@property
|
|
97
|
-
def
|
|
98
|
-
"""Return the
|
|
184
|
+
def connection_config_dict(self) -> dict[str, Any]:
|
|
185
|
+
"""Return the connection configuration as a dict for asyncmy.connect().
|
|
99
186
|
|
|
100
|
-
|
|
101
|
-
A string keyed dict of config kwargs for the Asyncmy create_pool function.
|
|
187
|
+
This method filters out pool-specific parameters that are not valid for asyncmy.connect().
|
|
102
188
|
"""
|
|
103
|
-
|
|
104
|
-
|
|
189
|
+
# Gather non-None connection parameters
|
|
190
|
+
config = {
|
|
191
|
+
field: getattr(self, field)
|
|
192
|
+
for field in CONNECTION_FIELDS
|
|
193
|
+
if getattr(self, field, None) is not None and getattr(self, field) is not Empty
|
|
194
|
+
}
|
|
105
195
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
"""Asyncmy Configuration."""
|
|
196
|
+
# Add connection-specific extras (not pool-specific ones)
|
|
197
|
+
config.update(self.extras)
|
|
109
198
|
|
|
110
|
-
|
|
111
|
-
__supports_connection_pooling__ = True
|
|
112
|
-
|
|
113
|
-
pool_config: "Optional[AsyncmyPoolConfig]" = None
|
|
114
|
-
"""Asyncmy Pool configuration"""
|
|
115
|
-
connection_type: "type[Connection]" = field(hash=False, init=False, default_factory=lambda: Connection) # pyright: ignore
|
|
116
|
-
"""Type of the connection object"""
|
|
117
|
-
driver_type: "type[AsyncmyDriver]" = field(hash=False, init=False, default_factory=lambda: AsyncmyDriver)
|
|
118
|
-
"""Type of the driver object"""
|
|
119
|
-
pool_instance: "Optional[Pool]" = field(hash=False, default=None) # pyright: ignore[reportUnknownVariableType]
|
|
120
|
-
"""Instance of the pool"""
|
|
199
|
+
return config
|
|
121
200
|
|
|
122
201
|
@property
|
|
123
|
-
def
|
|
124
|
-
"""Return the
|
|
202
|
+
def pool_config_dict(self) -> dict[str, Any]:
|
|
203
|
+
"""Return the full pool configuration as a dict for asyncmy.create_pool().
|
|
125
204
|
|
|
126
205
|
Returns:
|
|
127
|
-
A
|
|
128
|
-
|
|
129
|
-
Raises:
|
|
130
|
-
ImproperConfigurationError: If the connection configuration is not provided.
|
|
206
|
+
A dictionary containing all pool configuration parameters.
|
|
131
207
|
"""
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
convert_nested=False,
|
|
139
|
-
exclude=pool_only_params.union({"pool_instance", "driver_type", "connection_type"}),
|
|
140
|
-
)
|
|
141
|
-
msg = "You must provide a 'pool_config' for this adapter."
|
|
142
|
-
raise ImproperConfigurationError(msg)
|
|
208
|
+
# Gather non-None parameters from all fields (connection + pool)
|
|
209
|
+
config = {
|
|
210
|
+
field: getattr(self, field)
|
|
211
|
+
for field in POOL_FIELDS
|
|
212
|
+
if getattr(self, field, None) is not None and getattr(self, field) is not Empty
|
|
213
|
+
}
|
|
143
214
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
"""Return the pool configuration as a dict.
|
|
215
|
+
# Merge extras parameters
|
|
216
|
+
config.update(self.extras)
|
|
147
217
|
|
|
148
|
-
|
|
149
|
-
A string keyed dict of config kwargs for the Asyncmy create_pool function.
|
|
150
|
-
|
|
151
|
-
Raises:
|
|
152
|
-
ImproperConfigurationError: If the pool configuration is not provided.
|
|
153
|
-
"""
|
|
154
|
-
if self.pool_config:
|
|
155
|
-
return dataclass_to_dict(
|
|
156
|
-
self.pool_config,
|
|
157
|
-
exclude_empty=True,
|
|
158
|
-
convert_nested=False,
|
|
159
|
-
exclude={"pool_instance", "driver_type", "connection_type"},
|
|
160
|
-
)
|
|
161
|
-
msg = "'pool_config' methods can not be used when a 'pool_instance' is provided."
|
|
162
|
-
raise ImproperConfigurationError(msg)
|
|
163
|
-
|
|
164
|
-
async def create_connection(self) -> "Connection": # pyright: ignore[reportUnknownParameterType]
|
|
165
|
-
"""Create and return a new asyncmy connection from the pool.
|
|
218
|
+
return config
|
|
166
219
|
|
|
167
|
-
|
|
168
|
-
|
|
220
|
+
async def _create_pool(self) -> "Pool": # pyright: ignore
|
|
221
|
+
"""Create the actual async connection pool."""
|
|
222
|
+
return await asyncmy.create_pool(**self.pool_config_dict)
|
|
169
223
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
async with self.provide_connection() as conn:
|
|
175
|
-
return conn
|
|
176
|
-
except Exception as e:
|
|
177
|
-
msg = f"Could not configure the Asyncmy connection. Error: {e!s}"
|
|
178
|
-
raise ImproperConfigurationError(msg) from e
|
|
224
|
+
async def _close_pool(self) -> None:
|
|
225
|
+
"""Close the actual async connection pool."""
|
|
226
|
+
if self.pool_instance:
|
|
227
|
+
await self.pool_instance.close()
|
|
179
228
|
|
|
180
|
-
async def
|
|
181
|
-
"""
|
|
229
|
+
async def create_connection(self) -> AsyncmyConnection: # pyright: ignore
|
|
230
|
+
"""Create a single async connection (not from pool).
|
|
182
231
|
|
|
183
232
|
Returns:
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
Raises:
|
|
187
|
-
ImproperConfigurationError: If the pool could not be created.
|
|
233
|
+
An Asyncmy connection instance.
|
|
188
234
|
"""
|
|
189
|
-
if self.pool_instance is
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
if self.pool_config is None:
|
|
193
|
-
msg = "One of 'pool_config' or 'pool_instance' must be provided."
|
|
194
|
-
raise ImproperConfigurationError(msg)
|
|
235
|
+
if self.pool_instance is None:
|
|
236
|
+
self.pool_instance = await self.create_pool()
|
|
237
|
+
return await self.pool_instance.acquire() # pyright: ignore
|
|
195
238
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
self.pool_instance = await asyncmy.create_pool(**self.pool_config_dict) # pyright: ignore[reportUnknownMemberType]
|
|
200
|
-
except Exception as e:
|
|
201
|
-
msg = f"Could not configure the Asyncmy pool. Error: {e!s}"
|
|
202
|
-
raise ImproperConfigurationError(msg) from e
|
|
203
|
-
else:
|
|
204
|
-
return self.pool_instance # pyright: ignore[reportUnknownVariableType,reportUnknownMemberType]
|
|
239
|
+
@asynccontextmanager
|
|
240
|
+
async def provide_connection(self, *args: Any, **kwargs: Any) -> AsyncGenerator[AsyncmyConnection, None]: # pyright: ignore
|
|
241
|
+
"""Provide an async connection context manager.
|
|
205
242
|
|
|
206
|
-
|
|
207
|
-
|
|
243
|
+
Args:
|
|
244
|
+
*args: Additional arguments.
|
|
245
|
+
**kwargs: Additional keyword arguments.
|
|
208
246
|
|
|
209
|
-
|
|
210
|
-
|
|
247
|
+
Yields:
|
|
248
|
+
An Asyncmy connection instance.
|
|
211
249
|
"""
|
|
212
|
-
|
|
250
|
+
if self.pool_instance is None:
|
|
251
|
+
self.pool_instance = await self.create_pool()
|
|
252
|
+
async with self.pool_instance.acquire() as connection: # pyright: ignore
|
|
253
|
+
yield connection
|
|
213
254
|
|
|
214
255
|
@asynccontextmanager
|
|
215
|
-
async def
|
|
216
|
-
"""
|
|
256
|
+
async def provide_session(self, *args: Any, **kwargs: Any) -> AsyncGenerator[AsyncmyDriver, None]:
|
|
257
|
+
"""Provide an async driver session context manager.
|
|
217
258
|
|
|
218
|
-
|
|
219
|
-
|
|
259
|
+
Args:
|
|
260
|
+
*args: Additional arguments.
|
|
261
|
+
**kwargs: Additional keyword arguments.
|
|
220
262
|
|
|
263
|
+
Yields:
|
|
264
|
+
An AsyncmyDriver instance.
|
|
221
265
|
"""
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
266
|
+
async with self.provide_connection(*args, **kwargs) as connection:
|
|
267
|
+
# Create statement config with parameter style info if not already set
|
|
268
|
+
statement_config = self.statement_config
|
|
269
|
+
if statement_config.allowed_parameter_styles is None:
|
|
270
|
+
statement_config = replace(
|
|
271
|
+
statement_config,
|
|
272
|
+
allowed_parameter_styles=self.supported_parameter_styles,
|
|
273
|
+
target_parameter_style=self.preferred_parameter_style,
|
|
274
|
+
)
|
|
225
275
|
|
|
226
|
-
|
|
227
|
-
async def provide_session(self, *args: "Any", **kwargs: "Any") -> "AsyncGenerator[AsyncmyDriver, None]":
|
|
228
|
-
"""Create and provide a database session.
|
|
276
|
+
yield self.driver_type(connection=connection, config=statement_config)
|
|
229
277
|
|
|
230
|
-
|
|
231
|
-
|
|
278
|
+
async def provide_pool(self, *args: Any, **kwargs: Any) -> "Pool": # pyright: ignore
|
|
279
|
+
"""Provide async pool instance.
|
|
232
280
|
|
|
281
|
+
Returns:
|
|
282
|
+
The async connection pool.
|
|
233
283
|
"""
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
async def close_pool(self) -> None:
|
|
238
|
-
"""Close the connection pool."""
|
|
239
|
-
if self.pool_instance is not None: # pyright: ignore[reportUnknownMemberType]
|
|
240
|
-
await self.pool_instance.close() # pyright: ignore[reportUnknownMemberType]
|
|
241
|
-
self.pool_instance = None
|
|
284
|
+
if not self.pool_instance:
|
|
285
|
+
self.pool_instance = await self.create_pool()
|
|
286
|
+
return self.pool_instance
|