sqlspec 0.14.0__py3-none-any.whl → 0.15.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 +50 -25
- sqlspec/__main__.py +12 -0
- sqlspec/__metadata__.py +1 -3
- sqlspec/_serialization.py +1 -2
- sqlspec/_sql.py +256 -120
- sqlspec/_typing.py +278 -142
- sqlspec/adapters/adbc/__init__.py +4 -3
- sqlspec/adapters/adbc/_types.py +12 -0
- sqlspec/adapters/adbc/config.py +115 -248
- sqlspec/adapters/adbc/driver.py +462 -353
- sqlspec/adapters/aiosqlite/__init__.py +18 -3
- sqlspec/adapters/aiosqlite/_types.py +13 -0
- sqlspec/adapters/aiosqlite/config.py +199 -129
- sqlspec/adapters/aiosqlite/driver.py +230 -269
- sqlspec/adapters/asyncmy/__init__.py +18 -3
- sqlspec/adapters/asyncmy/_types.py +12 -0
- sqlspec/adapters/asyncmy/config.py +80 -168
- sqlspec/adapters/asyncmy/driver.py +260 -225
- sqlspec/adapters/asyncpg/__init__.py +19 -4
- sqlspec/adapters/asyncpg/_types.py +17 -0
- sqlspec/adapters/asyncpg/config.py +82 -181
- sqlspec/adapters/asyncpg/driver.py +285 -383
- sqlspec/adapters/bigquery/__init__.py +17 -3
- sqlspec/adapters/bigquery/_types.py +12 -0
- sqlspec/adapters/bigquery/config.py +191 -258
- sqlspec/adapters/bigquery/driver.py +474 -646
- sqlspec/adapters/duckdb/__init__.py +14 -3
- sqlspec/adapters/duckdb/_types.py +12 -0
- sqlspec/adapters/duckdb/config.py +415 -351
- sqlspec/adapters/duckdb/driver.py +343 -413
- sqlspec/adapters/oracledb/__init__.py +19 -5
- sqlspec/adapters/oracledb/_types.py +14 -0
- sqlspec/adapters/oracledb/config.py +123 -379
- sqlspec/adapters/oracledb/driver.py +507 -560
- sqlspec/adapters/psqlpy/__init__.py +13 -3
- sqlspec/adapters/psqlpy/_types.py +11 -0
- sqlspec/adapters/psqlpy/config.py +93 -254
- sqlspec/adapters/psqlpy/driver.py +505 -234
- sqlspec/adapters/psycopg/__init__.py +19 -5
- sqlspec/adapters/psycopg/_types.py +17 -0
- sqlspec/adapters/psycopg/config.py +143 -403
- sqlspec/adapters/psycopg/driver.py +706 -872
- sqlspec/adapters/sqlite/__init__.py +14 -3
- sqlspec/adapters/sqlite/_types.py +11 -0
- sqlspec/adapters/sqlite/config.py +202 -118
- sqlspec/adapters/sqlite/driver.py +264 -303
- sqlspec/base.py +105 -9
- sqlspec/{statement/builder → builder}/__init__.py +12 -14
- sqlspec/{statement/builder → builder}/_base.py +120 -55
- sqlspec/{statement/builder → builder}/_column.py +17 -6
- sqlspec/{statement/builder → builder}/_ddl.py +46 -79
- sqlspec/{statement/builder → builder}/_ddl_utils.py +5 -10
- sqlspec/{statement/builder → builder}/_delete.py +6 -25
- sqlspec/{statement/builder → builder}/_insert.py +6 -64
- sqlspec/builder/_merge.py +56 -0
- sqlspec/{statement/builder → builder}/_parsing_utils.py +3 -10
- sqlspec/{statement/builder → builder}/_select.py +11 -56
- sqlspec/{statement/builder → builder}/_update.py +12 -18
- sqlspec/{statement/builder → builder}/mixins/__init__.py +10 -14
- sqlspec/{statement/builder → builder}/mixins/_cte_and_set_ops.py +48 -59
- sqlspec/{statement/builder → builder}/mixins/_insert_operations.py +22 -16
- sqlspec/{statement/builder → builder}/mixins/_join_operations.py +1 -3
- sqlspec/{statement/builder → builder}/mixins/_merge_operations.py +3 -5
- sqlspec/{statement/builder → builder}/mixins/_order_limit_operations.py +3 -3
- sqlspec/{statement/builder → builder}/mixins/_pivot_operations.py +4 -8
- sqlspec/{statement/builder → builder}/mixins/_select_operations.py +21 -36
- sqlspec/{statement/builder → builder}/mixins/_update_operations.py +3 -14
- sqlspec/{statement/builder → builder}/mixins/_where_clause.py +52 -79
- sqlspec/cli.py +4 -5
- sqlspec/config.py +180 -133
- sqlspec/core/__init__.py +63 -0
- sqlspec/core/cache.py +873 -0
- sqlspec/core/compiler.py +396 -0
- sqlspec/core/filters.py +828 -0
- sqlspec/core/hashing.py +310 -0
- sqlspec/core/parameters.py +1209 -0
- sqlspec/core/result.py +664 -0
- sqlspec/{statement → core}/splitter.py +321 -191
- sqlspec/core/statement.py +651 -0
- sqlspec/driver/__init__.py +7 -10
- sqlspec/driver/_async.py +387 -176
- sqlspec/driver/_common.py +527 -289
- sqlspec/driver/_sync.py +390 -172
- sqlspec/driver/mixins/__init__.py +2 -19
- sqlspec/driver/mixins/_result_tools.py +168 -0
- sqlspec/driver/mixins/_sql_translator.py +6 -3
- sqlspec/exceptions.py +5 -252
- sqlspec/extensions/aiosql/adapter.py +93 -96
- sqlspec/extensions/litestar/config.py +0 -1
- sqlspec/extensions/litestar/handlers.py +15 -26
- sqlspec/extensions/litestar/plugin.py +16 -14
- sqlspec/extensions/litestar/providers.py +17 -52
- sqlspec/loader.py +424 -105
- sqlspec/migrations/__init__.py +12 -0
- sqlspec/migrations/base.py +92 -68
- sqlspec/migrations/commands.py +24 -106
- sqlspec/migrations/loaders.py +402 -0
- sqlspec/migrations/runner.py +49 -51
- sqlspec/migrations/tracker.py +31 -44
- sqlspec/migrations/utils.py +64 -24
- sqlspec/protocols.py +7 -183
- sqlspec/storage/__init__.py +1 -1
- sqlspec/storage/backends/base.py +37 -40
- sqlspec/storage/backends/fsspec.py +136 -112
- sqlspec/storage/backends/obstore.py +138 -160
- sqlspec/storage/capabilities.py +5 -4
- sqlspec/storage/registry.py +57 -106
- sqlspec/typing.py +136 -115
- sqlspec/utils/__init__.py +2 -3
- sqlspec/utils/correlation.py +0 -3
- sqlspec/utils/deprecation.py +6 -6
- sqlspec/utils/fixtures.py +6 -6
- sqlspec/utils/logging.py +0 -2
- sqlspec/utils/module_loader.py +7 -12
- sqlspec/utils/singleton.py +0 -1
- sqlspec/utils/sync_tools.py +16 -37
- sqlspec/utils/text.py +12 -51
- sqlspec/utils/type_guards.py +443 -232
- {sqlspec-0.14.0.dist-info → sqlspec-0.15.0.dist-info}/METADATA +7 -2
- sqlspec-0.15.0.dist-info/RECORD +134 -0
- sqlspec-0.15.0.dist-info/entry_points.txt +2 -0
- sqlspec/driver/connection.py +0 -207
- sqlspec/driver/mixins/_cache.py +0 -114
- sqlspec/driver/mixins/_csv_writer.py +0 -91
- sqlspec/driver/mixins/_pipeline.py +0 -508
- sqlspec/driver/mixins/_query_tools.py +0 -796
- sqlspec/driver/mixins/_result_utils.py +0 -138
- sqlspec/driver/mixins/_storage.py +0 -912
- sqlspec/driver/mixins/_type_coercion.py +0 -128
- sqlspec/driver/parameters.py +0 -138
- sqlspec/statement/__init__.py +0 -21
- sqlspec/statement/builder/_merge.py +0 -95
- sqlspec/statement/cache.py +0 -50
- sqlspec/statement/filters.py +0 -625
- sqlspec/statement/parameters.py +0 -996
- sqlspec/statement/pipelines/__init__.py +0 -210
- sqlspec/statement/pipelines/analyzers/__init__.py +0 -9
- sqlspec/statement/pipelines/analyzers/_analyzer.py +0 -646
- sqlspec/statement/pipelines/context.py +0 -115
- sqlspec/statement/pipelines/transformers/__init__.py +0 -7
- sqlspec/statement/pipelines/transformers/_expression_simplifier.py +0 -88
- sqlspec/statement/pipelines/transformers/_literal_parameterizer.py +0 -1247
- sqlspec/statement/pipelines/transformers/_remove_comments_and_hints.py +0 -76
- sqlspec/statement/pipelines/validators/__init__.py +0 -23
- sqlspec/statement/pipelines/validators/_dml_safety.py +0 -290
- sqlspec/statement/pipelines/validators/_parameter_style.py +0 -370
- sqlspec/statement/pipelines/validators/_performance.py +0 -714
- sqlspec/statement/pipelines/validators/_security.py +0 -967
- sqlspec/statement/result.py +0 -435
- sqlspec/statement/sql.py +0 -1774
- sqlspec/utils/cached_property.py +0 -25
- sqlspec/utils/statement_hashing.py +0 -203
- sqlspec-0.14.0.dist-info/RECORD +0 -143
- sqlspec-0.14.0.dist-info/entry_points.txt +0 -2
- /sqlspec/{statement/builder → builder}/mixins/_delete_operations.py +0 -0
- {sqlspec-0.14.0.dist-info → sqlspec-0.15.0.dist-info}/WHEEL +0 -0
- {sqlspec-0.14.0.dist-info → sqlspec-0.15.0.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.14.0.dist-info → sqlspec-0.15.0.dist-info}/licenses/NOTICE +0 -0
sqlspec/adapters/adbc/config.py
CHANGED
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
import logging
|
|
4
4
|
from contextlib import contextmanager
|
|
5
|
-
from
|
|
6
|
-
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Optional
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Optional, TypedDict, Union
|
|
7
6
|
|
|
8
|
-
from
|
|
7
|
+
from typing_extensions import NotRequired
|
|
8
|
+
|
|
9
|
+
from sqlspec.adapters.adbc._types import AdbcConnection
|
|
10
|
+
from sqlspec.adapters.adbc.driver import AdbcCursor, AdbcDriver, get_adbc_statement_config
|
|
9
11
|
from sqlspec.config import NoPoolSyncConfig
|
|
12
|
+
from sqlspec.core.statement import StatementConfig
|
|
10
13
|
from sqlspec.exceptions import ImproperConfigurationError
|
|
11
|
-
from sqlspec.statement.sql import SQLConfig
|
|
12
|
-
from sqlspec.typing import DictRow, Empty
|
|
13
14
|
from sqlspec.utils.module_loader import import_string
|
|
14
15
|
|
|
15
16
|
if TYPE_CHECKING:
|
|
@@ -20,219 +21,103 @@ if TYPE_CHECKING:
|
|
|
20
21
|
|
|
21
22
|
logger = logging.getLogger("sqlspec.adapters.adbc")
|
|
22
23
|
|
|
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
|
-
|
|
24
|
+
|
|
25
|
+
class AdbcConnectionParams(TypedDict, total=False):
|
|
26
|
+
"""ADBC connection parameters."""
|
|
27
|
+
|
|
28
|
+
uri: NotRequired[str]
|
|
29
|
+
driver_name: NotRequired[str]
|
|
30
|
+
db_kwargs: NotRequired[dict[str, Any]]
|
|
31
|
+
conn_kwargs: NotRequired[dict[str, Any]]
|
|
32
|
+
adbc_driver_manager_entrypoint: NotRequired[str]
|
|
33
|
+
autocommit: NotRequired[bool]
|
|
34
|
+
isolation_level: NotRequired[str]
|
|
35
|
+
batch_size: NotRequired[int]
|
|
36
|
+
query_timeout: NotRequired[float]
|
|
37
|
+
connection_timeout: NotRequired[float]
|
|
38
|
+
ssl_mode: NotRequired[str]
|
|
39
|
+
ssl_cert: NotRequired[str]
|
|
40
|
+
ssl_key: NotRequired[str]
|
|
41
|
+
ssl_ca: NotRequired[str]
|
|
42
|
+
username: NotRequired[str]
|
|
43
|
+
password: NotRequired[str]
|
|
44
|
+
token: NotRequired[str]
|
|
45
|
+
project_id: NotRequired[str]
|
|
46
|
+
dataset_id: NotRequired[str]
|
|
47
|
+
account: NotRequired[str]
|
|
48
|
+
warehouse: NotRequired[str]
|
|
49
|
+
database: NotRequired[str]
|
|
50
|
+
schema: NotRequired[str]
|
|
51
|
+
role: NotRequired[str]
|
|
52
|
+
authorization_header: NotRequired[str]
|
|
53
|
+
grpc_options: NotRequired[dict[str, Any]]
|
|
54
|
+
extra: NotRequired[dict[str, Any]]
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
__all__ = ("AdbcConfig", "AdbcConnectionParams")
|
|
55
58
|
|
|
56
59
|
|
|
57
60
|
class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
|
|
58
|
-
"""
|
|
61
|
+
"""ADBC configuration for Arrow Database Connectivity.
|
|
59
62
|
|
|
60
63
|
ADBC (Arrow Database Connectivity) provides a unified interface for connecting
|
|
61
|
-
to multiple database systems with
|
|
64
|
+
to multiple database systems with Arrow-native data transfer.
|
|
62
65
|
|
|
63
66
|
This configuration supports:
|
|
64
67
|
- Universal driver detection and loading
|
|
65
|
-
-
|
|
68
|
+
- Arrow data streaming
|
|
66
69
|
- Bulk ingestion operations
|
|
67
70
|
- Multiple database backends (PostgreSQL, SQLite, DuckDB, BigQuery, Snowflake, etc.)
|
|
68
|
-
-
|
|
71
|
+
- Driver path resolution
|
|
69
72
|
- Cloud database integrations
|
|
70
73
|
"""
|
|
71
74
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
driver_type: type[AdbcDriver] = AdbcDriver
|
|
75
|
-
connection_type: type[AdbcConnection] = AdbcConnection
|
|
76
|
-
|
|
77
|
-
# Parameter style support information - dynamic based on driver
|
|
78
|
-
# These are used as defaults when driver cannot be determined
|
|
79
|
-
supported_parameter_styles: ClassVar[tuple[str, ...]] = ("qmark",)
|
|
80
|
-
"""ADBC parameter styles depend on the underlying driver."""
|
|
81
|
-
|
|
82
|
-
default_parameter_style: ClassVar[str] = "qmark"
|
|
83
|
-
"""ADBC default parameter style is ? (qmark)."""
|
|
75
|
+
driver_type: ClassVar[type[AdbcDriver]] = AdbcDriver
|
|
76
|
+
connection_type: "ClassVar[type[AdbcConnection]]" = AdbcConnection
|
|
84
77
|
|
|
85
78
|
def __init__(
|
|
86
79
|
self,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
uri: Optional[str] = None,
|
|
92
|
-
driver_name: Optional[str] = None,
|
|
93
|
-
# Database-specific parameters
|
|
94
|
-
db_kwargs: Optional[dict[str, Any]] = None,
|
|
95
|
-
conn_kwargs: Optional[dict[str, Any]] = None,
|
|
96
|
-
# Driver-specific configurations
|
|
97
|
-
adbc_driver_manager_entrypoint: Optional[str] = None,
|
|
98
|
-
# Connection options
|
|
99
|
-
autocommit: Optional[bool] = None,
|
|
100
|
-
isolation_level: Optional[str] = None,
|
|
101
|
-
# Performance options
|
|
102
|
-
batch_size: Optional[int] = None,
|
|
103
|
-
query_timeout: Optional[int] = None,
|
|
104
|
-
connection_timeout: Optional[int] = None,
|
|
105
|
-
# Security options
|
|
106
|
-
ssl_mode: Optional[str] = None,
|
|
107
|
-
ssl_cert: Optional[str] = None,
|
|
108
|
-
ssl_key: Optional[str] = None,
|
|
109
|
-
ssl_ca: Optional[str] = None,
|
|
110
|
-
# Authentication
|
|
111
|
-
username: Optional[str] = None,
|
|
112
|
-
password: Optional[str] = None,
|
|
113
|
-
token: Optional[str] = None,
|
|
114
|
-
# Cloud-specific options
|
|
115
|
-
project_id: Optional[str] = None,
|
|
116
|
-
dataset_id: Optional[str] = None,
|
|
117
|
-
account: Optional[str] = None,
|
|
118
|
-
warehouse: Optional[str] = None,
|
|
119
|
-
database: Optional[str] = None,
|
|
120
|
-
schema: Optional[str] = None,
|
|
121
|
-
role: Optional[str] = None,
|
|
122
|
-
# Flight SQL specific
|
|
123
|
-
authorization_header: Optional[str] = None,
|
|
124
|
-
grpc_options: Optional[dict[str, Any]] = None,
|
|
125
|
-
**kwargs: Any,
|
|
80
|
+
*,
|
|
81
|
+
connection_config: Optional[Union[AdbcConnectionParams, dict[str, Any]]] = None,
|
|
82
|
+
statement_config: Optional[StatementConfig] = None,
|
|
83
|
+
migration_config: Optional[dict[str, Any]] = None,
|
|
126
84
|
) -> None:
|
|
127
|
-
"""Initialize ADBC configuration
|
|
85
|
+
"""Initialize ADBC configuration.
|
|
128
86
|
|
|
129
87
|
Args:
|
|
88
|
+
connection_config: Connection configuration parameters
|
|
130
89
|
statement_config: Default SQL statement configuration
|
|
131
|
-
|
|
132
|
-
default_row_type: Default row type for results
|
|
133
|
-
on_connection_create: Callback executed when connection is created
|
|
134
|
-
uri: Database URI (e.g., 'postgresql://...', 'sqlite://...', 'bigquery://...')
|
|
135
|
-
driver_name: Full dotted path to ADBC driver connect function or driver alias
|
|
136
|
-
driver: Backward compatibility alias for driver_name
|
|
137
|
-
db_kwargs: Additional database-specific connection parameters
|
|
138
|
-
conn_kwargs: Additional connection-specific parameters
|
|
139
|
-
adbc_driver_manager_entrypoint: Override for driver manager entrypoint
|
|
140
|
-
autocommit: Enable autocommit mode
|
|
141
|
-
isolation_level: Transaction isolation level
|
|
142
|
-
batch_size: Batch size for bulk operations
|
|
143
|
-
query_timeout: Query timeout in seconds
|
|
144
|
-
connection_timeout: Connection timeout in seconds
|
|
145
|
-
ssl_mode: SSL mode for secure connections
|
|
146
|
-
ssl_cert: SSL certificate path
|
|
147
|
-
ssl_key: SSL private key path
|
|
148
|
-
ssl_ca: SSL certificate authority path
|
|
149
|
-
username: Database username
|
|
150
|
-
password: Database password
|
|
151
|
-
token: Authentication token (for cloud services)
|
|
152
|
-
project_id: Project ID (BigQuery)
|
|
153
|
-
dataset_id: Dataset ID (BigQuery)
|
|
154
|
-
account: Account identifier (Snowflake)
|
|
155
|
-
warehouse: Warehouse name (Snowflake)
|
|
156
|
-
database: Database name
|
|
157
|
-
schema: Schema name
|
|
158
|
-
role: Role name (Snowflake)
|
|
159
|
-
authorization_header: Authorization header for Flight SQL
|
|
160
|
-
grpc_options: gRPC specific options for Flight SQL
|
|
161
|
-
**kwargs: Additional parameters (stored in extras)
|
|
162
|
-
|
|
163
|
-
Example:
|
|
164
|
-
>>> # PostgreSQL via ADBC
|
|
165
|
-
>>> config = AdbcConfig(
|
|
166
|
-
... uri="postgresql://user:pass@localhost/db",
|
|
167
|
-
... driver_name="adbc_driver_postgresql",
|
|
168
|
-
... )
|
|
169
|
-
|
|
170
|
-
>>> # DuckDB via ADBC
|
|
171
|
-
>>> config = AdbcConfig(
|
|
172
|
-
... uri="duckdb://mydata.db",
|
|
173
|
-
... driver_name="duckdb",
|
|
174
|
-
... db_kwargs={"read_only": False},
|
|
175
|
-
... )
|
|
176
|
-
|
|
177
|
-
>>> # BigQuery via ADBC
|
|
178
|
-
>>> config = AdbcConfig(
|
|
179
|
-
... driver_name="bigquery",
|
|
180
|
-
... project_id="my-project",
|
|
181
|
-
... dataset_id="my_dataset",
|
|
182
|
-
... )
|
|
90
|
+
migration_config: Migration configuration
|
|
183
91
|
"""
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
self.
|
|
191
|
-
self.
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
self.project_id = project_id
|
|
204
|
-
self.dataset_id = dataset_id
|
|
205
|
-
self.account = account
|
|
206
|
-
self.warehouse = warehouse
|
|
207
|
-
self.database = database
|
|
208
|
-
self.schema = schema
|
|
209
|
-
self.role = role
|
|
210
|
-
self.authorization_header = authorization_header
|
|
211
|
-
self.grpc_options = grpc_options
|
|
212
|
-
|
|
213
|
-
self.extras = kwargs or {}
|
|
214
|
-
|
|
215
|
-
# Store other config
|
|
216
|
-
self.statement_config = statement_config or SQLConfig()
|
|
217
|
-
self.default_row_type = default_row_type
|
|
218
|
-
self.on_connection_create = on_connection_create
|
|
219
|
-
super().__init__()
|
|
92
|
+
if connection_config is None:
|
|
93
|
+
connection_config = {}
|
|
94
|
+
extras = connection_config.pop("extra", {})
|
|
95
|
+
if not isinstance(extras, dict):
|
|
96
|
+
msg = "The 'extra' field in connection_config must be a dictionary."
|
|
97
|
+
raise ImproperConfigurationError(msg)
|
|
98
|
+
self.connection_config: dict[str, Any] = dict(connection_config)
|
|
99
|
+
self.connection_config.update(extras)
|
|
100
|
+
|
|
101
|
+
if statement_config is None:
|
|
102
|
+
detected_dialect = str(self._get_dialect() or "sqlite")
|
|
103
|
+
statement_config = get_adbc_statement_config(detected_dialect)
|
|
104
|
+
|
|
105
|
+
super().__init__(
|
|
106
|
+
connection_config=self.connection_config,
|
|
107
|
+
migration_config=migration_config,
|
|
108
|
+
statement_config=statement_config,
|
|
109
|
+
driver_features={},
|
|
110
|
+
)
|
|
220
111
|
|
|
221
112
|
def _resolve_driver_name(self) -> str:
|
|
222
113
|
"""Resolve and normalize the ADBC driver name.
|
|
223
114
|
|
|
224
|
-
Supports both full driver paths and convenient aliases.
|
|
225
|
-
|
|
226
115
|
Returns:
|
|
227
116
|
The normalized driver connect function path.
|
|
228
|
-
|
|
229
|
-
Raises:
|
|
230
|
-
ImproperConfigurationError: If driver cannot be determined.
|
|
231
117
|
"""
|
|
232
|
-
driver_name = self.driver_name
|
|
233
|
-
uri = self.uri
|
|
118
|
+
driver_name = self.connection_config.get("driver_name")
|
|
119
|
+
uri = self.connection_config.get("uri")
|
|
234
120
|
|
|
235
|
-
# If explicit driver path is provided, normalize it
|
|
236
121
|
if isinstance(driver_name, str):
|
|
237
122
|
driver_aliases = {
|
|
238
123
|
"sqlite": "adbc_driver_sqlite.dbapi.connect",
|
|
@@ -262,9 +147,8 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
|
|
|
262
147
|
|
|
263
148
|
return resolved_driver
|
|
264
149
|
|
|
265
|
-
# Auto-detect from URI if no explicit driver
|
|
266
150
|
if isinstance(uri, str):
|
|
267
|
-
if uri.startswith("postgresql://"):
|
|
151
|
+
if uri.startswith(("postgresql://", "postgres://")):
|
|
268
152
|
return "adbc_driver_postgresql.dbapi.connect"
|
|
269
153
|
if uri.startswith("sqlite://"):
|
|
270
154
|
return "adbc_driver_sqlite.dbapi.connect"
|
|
@@ -277,13 +161,7 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
|
|
|
277
161
|
if uri.startswith("bigquery://"):
|
|
278
162
|
return "adbc_driver_bigquery.dbapi.connect"
|
|
279
163
|
|
|
280
|
-
|
|
281
|
-
msg = (
|
|
282
|
-
"Could not determine ADBC driver connect path. Please specify 'driver_name' "
|
|
283
|
-
"(e.g., 'adbc_driver_postgresql' or 'postgresql') or provide a supported 'uri'. "
|
|
284
|
-
f"URI: {uri}, Driver Name: {driver_name}"
|
|
285
|
-
)
|
|
286
|
-
raise ImproperConfigurationError(msg)
|
|
164
|
+
return "adbc_driver_sqlite.dbapi.connect"
|
|
287
165
|
|
|
288
166
|
def _get_connect_func(self) -> Callable[..., AdbcConnection]:
|
|
289
167
|
"""Get the ADBC driver connect function.
|
|
@@ -349,22 +227,19 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
|
|
|
349
227
|
"""
|
|
350
228
|
try:
|
|
351
229
|
driver_path = self._resolve_driver_name()
|
|
352
|
-
|
|
353
|
-
# Map driver paths to parameter styles
|
|
354
230
|
if "postgresql" in driver_path:
|
|
355
|
-
return (("numeric",), "numeric")
|
|
231
|
+
return (("numeric",), "numeric")
|
|
356
232
|
if "sqlite" in driver_path:
|
|
357
|
-
return (("qmark", "named_colon"), "qmark")
|
|
233
|
+
return (("qmark", "named_colon"), "qmark")
|
|
358
234
|
if "duckdb" in driver_path:
|
|
359
|
-
return (("qmark", "numeric"), "qmark")
|
|
235
|
+
return (("qmark", "numeric"), "qmark")
|
|
360
236
|
if "bigquery" in driver_path:
|
|
361
|
-
return (("named_at",), "named_at")
|
|
237
|
+
return (("named_at",), "named_at")
|
|
362
238
|
if "snowflake" in driver_path:
|
|
363
|
-
return (("qmark", "numeric"), "qmark")
|
|
239
|
+
return (("qmark", "numeric"), "qmark")
|
|
364
240
|
|
|
365
241
|
except Exception:
|
|
366
|
-
|
|
367
|
-
return (self.supported_parameter_styles, self.default_parameter_style)
|
|
242
|
+
logger.debug("Error resolving parameter styles for ADBC driver, using defaults")
|
|
368
243
|
return (("qmark",), "qmark")
|
|
369
244
|
|
|
370
245
|
def create_connection(self) -> AdbcConnection:
|
|
@@ -379,12 +254,10 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
|
|
|
379
254
|
|
|
380
255
|
try:
|
|
381
256
|
connect_func = self._get_connect_func()
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
if self.on_connection_create:
|
|
385
|
-
self.on_connection_create(connection)
|
|
257
|
+
connection_config_dict = self._get_connection_config_dict()
|
|
258
|
+
connection = connect_func(**connection_config_dict)
|
|
386
259
|
except Exception as e:
|
|
387
|
-
driver_name = self.driver_name
|
|
260
|
+
driver_name = self.connection_config.get("driver_name", "Unknown")
|
|
388
261
|
msg = f"Could not configure ADBC connection using driver '{driver_name}'. Error: {e}"
|
|
389
262
|
raise ImproperConfigurationError(msg) from e
|
|
390
263
|
return connection
|
|
@@ -406,11 +279,14 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
|
|
|
406
279
|
finally:
|
|
407
280
|
connection.close()
|
|
408
281
|
|
|
409
|
-
def provide_session(
|
|
282
|
+
def provide_session(
|
|
283
|
+
self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
|
|
284
|
+
) -> "AbstractContextManager[AdbcDriver]":
|
|
410
285
|
"""Provide an ADBC driver session context manager.
|
|
411
286
|
|
|
412
287
|
Args:
|
|
413
288
|
*args: Additional arguments.
|
|
289
|
+
statement_config: Optional statement configuration override.
|
|
414
290
|
**kwargs: Additional keyword arguments.
|
|
415
291
|
|
|
416
292
|
Returns:
|
|
@@ -420,41 +296,22 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
|
|
|
420
296
|
@contextmanager
|
|
421
297
|
def session_manager() -> "Generator[AdbcDriver, None, None]":
|
|
422
298
|
with self.provide_connection(*args, **kwargs) as connection:
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
if statement_config.allowed_parameter_styles is None:
|
|
431
|
-
statement_config = replace(
|
|
432
|
-
statement_config,
|
|
433
|
-
allowed_parameter_styles=supported_styles,
|
|
434
|
-
default_parameter_style=preferred_style,
|
|
435
|
-
)
|
|
436
|
-
|
|
437
|
-
driver = self.driver_type(connection=connection, config=statement_config)
|
|
438
|
-
yield driver
|
|
299
|
+
final_statement_config = (
|
|
300
|
+
statement_config
|
|
301
|
+
or self.statement_config
|
|
302
|
+
or get_adbc_statement_config(str(self._get_dialect() or "sqlite"))
|
|
303
|
+
)
|
|
304
|
+
yield self.driver_type(connection=connection, statement_config=final_statement_config)
|
|
439
305
|
|
|
440
306
|
return session_manager()
|
|
441
307
|
|
|
442
|
-
|
|
443
|
-
def connection_config_dict(self) -> dict[str, Any]:
|
|
308
|
+
def _get_connection_config_dict(self) -> dict[str, Any]:
|
|
444
309
|
"""Get the connection configuration dictionary.
|
|
445
310
|
|
|
446
311
|
Returns:
|
|
447
312
|
The connection configuration dictionary.
|
|
448
313
|
"""
|
|
449
|
-
|
|
450
|
-
config = {
|
|
451
|
-
field: getattr(self, field)
|
|
452
|
-
for field in CONNECTION_FIELDS
|
|
453
|
-
if getattr(self, field, None) is not None and getattr(self, field) is not Empty
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
# Merge extras parameters
|
|
457
|
-
config.update(self.extras)
|
|
314
|
+
config = dict(self.connection_config)
|
|
458
315
|
|
|
459
316
|
if "driver_name" in config:
|
|
460
317
|
driver_name = config["driver_name"]
|
|
@@ -462,28 +319,24 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
|
|
|
462
319
|
if "uri" in config:
|
|
463
320
|
uri = config["uri"]
|
|
464
321
|
|
|
465
|
-
# SQLite: strip sqlite:// prefix
|
|
466
322
|
if driver_name in {"sqlite", "sqlite3", "adbc_driver_sqlite"} and uri.startswith("sqlite://"): # pyright: ignore
|
|
467
|
-
config["uri"] = uri[9:] #
|
|
323
|
+
config["uri"] = uri[9:] # pyright: ignore
|
|
468
324
|
|
|
469
|
-
# DuckDB: convert uri to path
|
|
470
325
|
elif driver_name in {"duckdb", "adbc_driver_duckdb"} and uri.startswith("duckdb://"): # pyright: ignore
|
|
471
|
-
config["path"] = uri[9:] #
|
|
326
|
+
config["path"] = uri[9:] # pyright: ignore
|
|
472
327
|
config.pop("uri", None)
|
|
473
328
|
|
|
474
|
-
# BigQuery: wrap certain parameters in db_kwargs
|
|
475
329
|
if driver_name in {"bigquery", "bq", "adbc_driver_bigquery"}:
|
|
476
|
-
|
|
330
|
+
bigquery_parameters = ["project_id", "dataset_id", "token"]
|
|
477
331
|
db_kwargs = config.get("db_kwargs", {})
|
|
478
332
|
|
|
479
|
-
for param in
|
|
333
|
+
for param in bigquery_parameters:
|
|
480
334
|
if param in config and param != "db_kwargs":
|
|
481
335
|
db_kwargs[param] = config.pop(param) # pyright: ignore
|
|
482
336
|
|
|
483
337
|
if db_kwargs:
|
|
484
338
|
config["db_kwargs"] = db_kwargs
|
|
485
339
|
|
|
486
|
-
# For other drivers (like PostgreSQL), merge db_kwargs into top level
|
|
487
340
|
elif "db_kwargs" in config and driver_name not in {"bigquery", "bq", "adbc_driver_bigquery"}:
|
|
488
341
|
db_kwargs = config.pop("db_kwargs")
|
|
489
342
|
if isinstance(db_kwargs, dict):
|
|
@@ -492,3 +345,17 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
|
|
|
492
345
|
config.pop("driver_name", None)
|
|
493
346
|
|
|
494
347
|
return config
|
|
348
|
+
|
|
349
|
+
def get_signature_namespace(self) -> "dict[str, type[Any]]":
|
|
350
|
+
"""Get the signature namespace for ADBC types.
|
|
351
|
+
|
|
352
|
+
This provides all ADBC-specific types that Litestar needs to recognize
|
|
353
|
+
to avoid serialization attempts.
|
|
354
|
+
|
|
355
|
+
Returns:
|
|
356
|
+
Dictionary mapping type names to types.
|
|
357
|
+
"""
|
|
358
|
+
|
|
359
|
+
namespace = super().get_signature_namespace()
|
|
360
|
+
namespace.update({"AdbcConnection": AdbcConnection, "AdbcCursor": AdbcCursor})
|
|
361
|
+
return namespace
|