sqlspec 0.13.1__py3-none-any.whl → 0.16.2__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 +71 -8
- sqlspec/__main__.py +12 -0
- sqlspec/__metadata__.py +1 -3
- sqlspec/_serialization.py +1 -2
- sqlspec/_sql.py +930 -136
- sqlspec/_typing.py +278 -142
- sqlspec/adapters/adbc/__init__.py +4 -3
- sqlspec/adapters/adbc/_types.py +12 -0
- sqlspec/adapters/adbc/config.py +116 -285
- sqlspec/adapters/adbc/driver.py +462 -340
- sqlspec/adapters/aiosqlite/__init__.py +18 -3
- sqlspec/adapters/aiosqlite/_types.py +13 -0
- sqlspec/adapters/aiosqlite/config.py +202 -150
- sqlspec/adapters/aiosqlite/driver.py +226 -247
- sqlspec/adapters/asyncmy/__init__.py +18 -3
- sqlspec/adapters/asyncmy/_types.py +12 -0
- sqlspec/adapters/asyncmy/config.py +80 -199
- sqlspec/adapters/asyncmy/driver.py +257 -215
- sqlspec/adapters/asyncpg/__init__.py +19 -4
- sqlspec/adapters/asyncpg/_types.py +17 -0
- sqlspec/adapters/asyncpg/config.py +81 -214
- sqlspec/adapters/asyncpg/driver.py +284 -359
- sqlspec/adapters/bigquery/__init__.py +17 -3
- sqlspec/adapters/bigquery/_types.py +12 -0
- sqlspec/adapters/bigquery/config.py +191 -299
- sqlspec/adapters/bigquery/driver.py +474 -634
- sqlspec/adapters/duckdb/__init__.py +14 -3
- sqlspec/adapters/duckdb/_types.py +12 -0
- sqlspec/adapters/duckdb/config.py +414 -397
- sqlspec/adapters/duckdb/driver.py +342 -393
- sqlspec/adapters/oracledb/__init__.py +19 -5
- sqlspec/adapters/oracledb/_types.py +14 -0
- sqlspec/adapters/oracledb/config.py +123 -458
- sqlspec/adapters/oracledb/driver.py +505 -531
- sqlspec/adapters/psqlpy/__init__.py +13 -3
- sqlspec/adapters/psqlpy/_types.py +11 -0
- sqlspec/adapters/psqlpy/config.py +93 -307
- sqlspec/adapters/psqlpy/driver.py +504 -213
- sqlspec/adapters/psycopg/__init__.py +19 -5
- sqlspec/adapters/psycopg/_types.py +17 -0
- sqlspec/adapters/psycopg/config.py +143 -472
- sqlspec/adapters/psycopg/driver.py +704 -825
- sqlspec/adapters/sqlite/__init__.py +14 -3
- sqlspec/adapters/sqlite/_types.py +11 -0
- sqlspec/adapters/sqlite/config.py +208 -142
- sqlspec/adapters/sqlite/driver.py +263 -278
- sqlspec/base.py +105 -9
- sqlspec/{statement/builder → builder}/__init__.py +12 -14
- sqlspec/{statement/builder/base.py → builder/_base.py} +184 -86
- sqlspec/{statement/builder/column.py → builder/_column.py} +97 -60
- sqlspec/{statement/builder/ddl.py → builder/_ddl.py} +61 -131
- sqlspec/{statement/builder → builder}/_ddl_utils.py +4 -10
- sqlspec/{statement/builder/delete.py → builder/_delete.py} +10 -30
- sqlspec/builder/_insert.py +421 -0
- sqlspec/builder/_merge.py +71 -0
- sqlspec/{statement/builder → builder}/_parsing_utils.py +49 -26
- sqlspec/builder/_select.py +170 -0
- sqlspec/{statement/builder/update.py → builder/_update.py} +16 -20
- sqlspec/builder/mixins/__init__.py +55 -0
- sqlspec/builder/mixins/_cte_and_set_ops.py +222 -0
- sqlspec/{statement/builder/mixins/_delete_from.py → builder/mixins/_delete_operations.py} +8 -1
- sqlspec/builder/mixins/_insert_operations.py +244 -0
- sqlspec/{statement/builder/mixins/_join.py → builder/mixins/_join_operations.py} +45 -13
- sqlspec/{statement/builder/mixins/_merge_clauses.py → builder/mixins/_merge_operations.py} +188 -30
- sqlspec/builder/mixins/_order_limit_operations.py +135 -0
- sqlspec/builder/mixins/_pivot_operations.py +153 -0
- sqlspec/builder/mixins/_select_operations.py +604 -0
- sqlspec/builder/mixins/_update_operations.py +202 -0
- sqlspec/builder/mixins/_where_clause.py +644 -0
- sqlspec/cli.py +247 -0
- sqlspec/config.py +183 -138
- sqlspec/core/__init__.py +63 -0
- sqlspec/core/cache.py +871 -0
- sqlspec/core/compiler.py +417 -0
- sqlspec/core/filters.py +830 -0
- sqlspec/core/hashing.py +310 -0
- sqlspec/core/parameters.py +1237 -0
- sqlspec/core/result.py +677 -0
- sqlspec/{statement → core}/splitter.py +321 -191
- sqlspec/core/statement.py +676 -0
- sqlspec/driver/__init__.py +7 -10
- sqlspec/driver/_async.py +422 -163
- sqlspec/driver/_common.py +545 -287
- sqlspec/driver/_sync.py +426 -160
- sqlspec/driver/mixins/__init__.py +2 -13
- sqlspec/driver/mixins/_result_tools.py +193 -0
- sqlspec/driver/mixins/_sql_translator.py +65 -14
- sqlspec/exceptions.py +5 -252
- sqlspec/extensions/aiosql/adapter.py +93 -96
- sqlspec/extensions/litestar/__init__.py +2 -1
- sqlspec/extensions/litestar/cli.py +48 -0
- sqlspec/extensions/litestar/config.py +0 -1
- sqlspec/extensions/litestar/handlers.py +15 -26
- sqlspec/extensions/litestar/plugin.py +21 -16
- sqlspec/extensions/litestar/providers.py +17 -52
- sqlspec/loader.py +423 -104
- sqlspec/migrations/__init__.py +35 -0
- sqlspec/migrations/base.py +414 -0
- sqlspec/migrations/commands.py +443 -0
- sqlspec/migrations/loaders.py +402 -0
- sqlspec/migrations/runner.py +213 -0
- sqlspec/migrations/tracker.py +140 -0
- sqlspec/migrations/utils.py +129 -0
- sqlspec/protocols.py +51 -186
- 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 -2
- 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 +17 -38
- sqlspec/utils/text.py +12 -51
- sqlspec/utils/type_guards.py +482 -235
- {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/METADATA +7 -2
- sqlspec-0.16.2.dist-info/RECORD +134 -0
- sqlspec-0.16.2.dist-info/entry_points.txt +2 -0
- sqlspec/driver/connection.py +0 -207
- sqlspec/driver/mixins/_csv_writer.py +0 -91
- sqlspec/driver/mixins/_pipeline.py +0 -512
- sqlspec/driver/mixins/_result_utils.py +0 -140
- sqlspec/driver/mixins/_storage.py +0 -926
- sqlspec/driver/mixins/_type_coercion.py +0 -130
- sqlspec/driver/parameters.py +0 -138
- sqlspec/service/__init__.py +0 -4
- sqlspec/service/_util.py +0 -147
- sqlspec/service/base.py +0 -1131
- sqlspec/service/pagination.py +0 -26
- sqlspec/statement/__init__.py +0 -21
- sqlspec/statement/builder/insert.py +0 -288
- sqlspec/statement/builder/merge.py +0 -95
- sqlspec/statement/builder/mixins/__init__.py +0 -65
- sqlspec/statement/builder/mixins/_aggregate_functions.py +0 -250
- sqlspec/statement/builder/mixins/_case_builder.py +0 -91
- sqlspec/statement/builder/mixins/_common_table_expr.py +0 -90
- sqlspec/statement/builder/mixins/_from.py +0 -63
- sqlspec/statement/builder/mixins/_group_by.py +0 -118
- sqlspec/statement/builder/mixins/_having.py +0 -35
- sqlspec/statement/builder/mixins/_insert_from_select.py +0 -47
- sqlspec/statement/builder/mixins/_insert_into.py +0 -36
- sqlspec/statement/builder/mixins/_insert_values.py +0 -67
- sqlspec/statement/builder/mixins/_limit_offset.py +0 -53
- sqlspec/statement/builder/mixins/_order_by.py +0 -46
- sqlspec/statement/builder/mixins/_pivot.py +0 -79
- sqlspec/statement/builder/mixins/_returning.py +0 -37
- sqlspec/statement/builder/mixins/_select_columns.py +0 -61
- sqlspec/statement/builder/mixins/_set_ops.py +0 -122
- sqlspec/statement/builder/mixins/_unpivot.py +0 -77
- sqlspec/statement/builder/mixins/_update_from.py +0 -55
- sqlspec/statement/builder/mixins/_update_set.py +0 -94
- sqlspec/statement/builder/mixins/_update_table.py +0 -29
- sqlspec/statement/builder/mixins/_where.py +0 -401
- sqlspec/statement/builder/mixins/_window_functions.py +0 -86
- sqlspec/statement/builder/select.py +0 -221
- sqlspec/statement/filters.py +0 -596
- sqlspec/statement/parameter_manager.py +0 -220
- sqlspec/statement/parameters.py +0 -867
- 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 -718
- sqlspec/statement/pipelines/validators/_security.py +0 -967
- sqlspec/statement/result.py +0 -435
- sqlspec/statement/sql.py +0 -1704
- sqlspec/statement/sql_compiler.py +0 -140
- sqlspec/utils/cached_property.py +0 -25
- sqlspec-0.13.1.dist-info/RECORD +0 -150
- {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/WHEEL +0 -0
- {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.13.1.dist-info → sqlspec-0.16.2.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,255 +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
|
-
"account",
|
|
75
|
-
"adbc_driver_manager_entrypoint",
|
|
76
|
-
"authorization_header",
|
|
77
|
-
"autocommit",
|
|
78
|
-
"batch_size",
|
|
79
|
-
"conn_kwargs",
|
|
80
|
-
"connection_timeout",
|
|
81
|
-
"database",
|
|
82
|
-
"dataset_id",
|
|
83
|
-
"db_kwargs",
|
|
84
|
-
"default_row_type",
|
|
85
|
-
"driver_name",
|
|
86
|
-
"extras",
|
|
87
|
-
"grpc_options",
|
|
88
|
-
"isolation_level",
|
|
89
|
-
"on_connection_create",
|
|
90
|
-
"password",
|
|
91
|
-
"pool_instance",
|
|
92
|
-
"project_id",
|
|
93
|
-
"query_timeout",
|
|
94
|
-
"role",
|
|
95
|
-
"schema",
|
|
96
|
-
"ssl_ca",
|
|
97
|
-
"ssl_cert",
|
|
98
|
-
"ssl_key",
|
|
99
|
-
"ssl_mode",
|
|
100
|
-
"statement_config",
|
|
101
|
-
"token",
|
|
102
|
-
"uri",
|
|
103
|
-
"username",
|
|
104
|
-
"warehouse",
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
is_async: ClassVar[bool] = False
|
|
108
|
-
supports_connection_pooling: ClassVar[bool] = False
|
|
109
|
-
driver_type: type[AdbcDriver] = AdbcDriver
|
|
110
|
-
connection_type: type[AdbcConnection] = AdbcConnection
|
|
111
|
-
|
|
112
|
-
# Parameter style support information - dynamic based on driver
|
|
113
|
-
# These are used as defaults when driver cannot be determined
|
|
114
|
-
supported_parameter_styles: ClassVar[tuple[str, ...]] = ("qmark",)
|
|
115
|
-
"""ADBC parameter styles depend on the underlying driver."""
|
|
116
|
-
|
|
117
|
-
preferred_parameter_style: ClassVar[str] = "qmark"
|
|
118
|
-
"""ADBC default parameter style is ? (qmark)."""
|
|
75
|
+
driver_type: ClassVar[type[AdbcDriver]] = AdbcDriver
|
|
76
|
+
connection_type: "ClassVar[type[AdbcConnection]]" = AdbcConnection
|
|
119
77
|
|
|
120
78
|
def __init__(
|
|
121
79
|
self,
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
uri: Optional[str] = None,
|
|
127
|
-
driver_name: Optional[str] = None,
|
|
128
|
-
# Database-specific parameters
|
|
129
|
-
db_kwargs: Optional[dict[str, Any]] = None,
|
|
130
|
-
conn_kwargs: Optional[dict[str, Any]] = None,
|
|
131
|
-
# Driver-specific configurations
|
|
132
|
-
adbc_driver_manager_entrypoint: Optional[str] = None,
|
|
133
|
-
# Connection options
|
|
134
|
-
autocommit: Optional[bool] = None,
|
|
135
|
-
isolation_level: Optional[str] = None,
|
|
136
|
-
# Performance options
|
|
137
|
-
batch_size: Optional[int] = None,
|
|
138
|
-
query_timeout: Optional[int] = None,
|
|
139
|
-
connection_timeout: Optional[int] = None,
|
|
140
|
-
# Security options
|
|
141
|
-
ssl_mode: Optional[str] = None,
|
|
142
|
-
ssl_cert: Optional[str] = None,
|
|
143
|
-
ssl_key: Optional[str] = None,
|
|
144
|
-
ssl_ca: Optional[str] = None,
|
|
145
|
-
# Authentication
|
|
146
|
-
username: Optional[str] = None,
|
|
147
|
-
password: Optional[str] = None,
|
|
148
|
-
token: Optional[str] = None,
|
|
149
|
-
# Cloud-specific options
|
|
150
|
-
project_id: Optional[str] = None,
|
|
151
|
-
dataset_id: Optional[str] = None,
|
|
152
|
-
account: Optional[str] = None,
|
|
153
|
-
warehouse: Optional[str] = None,
|
|
154
|
-
database: Optional[str] = None,
|
|
155
|
-
schema: Optional[str] = None,
|
|
156
|
-
role: Optional[str] = None,
|
|
157
|
-
# Flight SQL specific
|
|
158
|
-
authorization_header: Optional[str] = None,
|
|
159
|
-
grpc_options: Optional[dict[str, Any]] = None,
|
|
160
|
-
**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,
|
|
161
84
|
) -> None:
|
|
162
|
-
"""Initialize ADBC configuration
|
|
85
|
+
"""Initialize ADBC configuration.
|
|
163
86
|
|
|
164
87
|
Args:
|
|
88
|
+
connection_config: Connection configuration parameters
|
|
165
89
|
statement_config: Default SQL statement configuration
|
|
166
|
-
|
|
167
|
-
default_row_type: Default row type for results
|
|
168
|
-
on_connection_create: Callback executed when connection is created
|
|
169
|
-
uri: Database URI (e.g., 'postgresql://...', 'sqlite://...', 'bigquery://...')
|
|
170
|
-
driver_name: Full dotted path to ADBC driver connect function or driver alias
|
|
171
|
-
driver: Backward compatibility alias for driver_name
|
|
172
|
-
db_kwargs: Additional database-specific connection parameters
|
|
173
|
-
conn_kwargs: Additional connection-specific parameters
|
|
174
|
-
adbc_driver_manager_entrypoint: Override for driver manager entrypoint
|
|
175
|
-
autocommit: Enable autocommit mode
|
|
176
|
-
isolation_level: Transaction isolation level
|
|
177
|
-
batch_size: Batch size for bulk operations
|
|
178
|
-
query_timeout: Query timeout in seconds
|
|
179
|
-
connection_timeout: Connection timeout in seconds
|
|
180
|
-
ssl_mode: SSL mode for secure connections
|
|
181
|
-
ssl_cert: SSL certificate path
|
|
182
|
-
ssl_key: SSL private key path
|
|
183
|
-
ssl_ca: SSL certificate authority path
|
|
184
|
-
username: Database username
|
|
185
|
-
password: Database password
|
|
186
|
-
token: Authentication token (for cloud services)
|
|
187
|
-
project_id: Project ID (BigQuery)
|
|
188
|
-
dataset_id: Dataset ID (BigQuery)
|
|
189
|
-
account: Account identifier (Snowflake)
|
|
190
|
-
warehouse: Warehouse name (Snowflake)
|
|
191
|
-
database: Database name
|
|
192
|
-
schema: Schema name
|
|
193
|
-
role: Role name (Snowflake)
|
|
194
|
-
authorization_header: Authorization header for Flight SQL
|
|
195
|
-
grpc_options: gRPC specific options for Flight SQL
|
|
196
|
-
**kwargs: Additional parameters (stored in extras)
|
|
197
|
-
|
|
198
|
-
Example:
|
|
199
|
-
>>> # PostgreSQL via ADBC
|
|
200
|
-
>>> config = AdbcConfig(
|
|
201
|
-
... uri="postgresql://user:pass@localhost/db",
|
|
202
|
-
... driver_name="adbc_driver_postgresql",
|
|
203
|
-
... )
|
|
204
|
-
|
|
205
|
-
>>> # DuckDB via ADBC
|
|
206
|
-
>>> config = AdbcConfig(
|
|
207
|
-
... uri="duckdb://mydata.db",
|
|
208
|
-
... driver_name="duckdb",
|
|
209
|
-
... db_kwargs={"read_only": False},
|
|
210
|
-
... )
|
|
211
|
-
|
|
212
|
-
>>> # BigQuery via ADBC
|
|
213
|
-
>>> config = AdbcConfig(
|
|
214
|
-
... driver_name="bigquery",
|
|
215
|
-
... project_id="my-project",
|
|
216
|
-
... dataset_id="my_dataset",
|
|
217
|
-
... )
|
|
90
|
+
migration_config: Migration configuration
|
|
218
91
|
"""
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
self.
|
|
226
|
-
self.
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
self.project_id = project_id
|
|
239
|
-
self.dataset_id = dataset_id
|
|
240
|
-
self.account = account
|
|
241
|
-
self.warehouse = warehouse
|
|
242
|
-
self.database = database
|
|
243
|
-
self.schema = schema
|
|
244
|
-
self.role = role
|
|
245
|
-
self.authorization_header = authorization_header
|
|
246
|
-
self.grpc_options = grpc_options
|
|
247
|
-
|
|
248
|
-
self.extras = kwargs or {}
|
|
249
|
-
|
|
250
|
-
# Store other config
|
|
251
|
-
self.statement_config = statement_config or SQLConfig()
|
|
252
|
-
self.default_row_type = default_row_type
|
|
253
|
-
self.on_connection_create = on_connection_create
|
|
254
|
-
self._dialect: DialectType = None
|
|
255
|
-
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
|
+
)
|
|
256
111
|
|
|
257
112
|
def _resolve_driver_name(self) -> str:
|
|
258
113
|
"""Resolve and normalize the ADBC driver name.
|
|
259
114
|
|
|
260
|
-
Supports both full driver paths and convenient aliases.
|
|
261
|
-
|
|
262
115
|
Returns:
|
|
263
116
|
The normalized driver connect function path.
|
|
264
|
-
|
|
265
|
-
Raises:
|
|
266
|
-
ImproperConfigurationError: If driver cannot be determined.
|
|
267
117
|
"""
|
|
268
|
-
driver_name = self.driver_name
|
|
269
|
-
uri = self.uri
|
|
118
|
+
driver_name = self.connection_config.get("driver_name")
|
|
119
|
+
uri = self.connection_config.get("uri")
|
|
270
120
|
|
|
271
|
-
# If explicit driver path is provided, normalize it
|
|
272
121
|
if isinstance(driver_name, str):
|
|
273
122
|
driver_aliases = {
|
|
274
123
|
"sqlite": "adbc_driver_sqlite.dbapi.connect",
|
|
@@ -298,9 +147,8 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
|
|
|
298
147
|
|
|
299
148
|
return resolved_driver
|
|
300
149
|
|
|
301
|
-
# Auto-detect from URI if no explicit driver
|
|
302
150
|
if isinstance(uri, str):
|
|
303
|
-
if uri.startswith("postgresql://"):
|
|
151
|
+
if uri.startswith(("postgresql://", "postgres://")):
|
|
304
152
|
return "adbc_driver_postgresql.dbapi.connect"
|
|
305
153
|
if uri.startswith("sqlite://"):
|
|
306
154
|
return "adbc_driver_sqlite.dbapi.connect"
|
|
@@ -313,13 +161,7 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
|
|
|
313
161
|
if uri.startswith("bigquery://"):
|
|
314
162
|
return "adbc_driver_bigquery.dbapi.connect"
|
|
315
163
|
|
|
316
|
-
|
|
317
|
-
msg = (
|
|
318
|
-
"Could not determine ADBC driver connect path. Please specify 'driver_name' "
|
|
319
|
-
"(e.g., 'adbc_driver_postgresql' or 'postgresql') or provide a supported 'uri'. "
|
|
320
|
-
f"URI: {uri}, Driver Name: {driver_name}"
|
|
321
|
-
)
|
|
322
|
-
raise ImproperConfigurationError(msg)
|
|
164
|
+
return "adbc_driver_sqlite.dbapi.connect"
|
|
323
165
|
|
|
324
166
|
def _get_connect_func(self) -> Callable[..., AdbcConnection]:
|
|
325
167
|
"""Get the ADBC driver connect function.
|
|
@@ -381,26 +223,23 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
|
|
|
381
223
|
"""Get parameter styles based on the underlying driver.
|
|
382
224
|
|
|
383
225
|
Returns:
|
|
384
|
-
Tuple of (supported_parameter_styles,
|
|
226
|
+
Tuple of (supported_parameter_styles, default_parameter_style)
|
|
385
227
|
"""
|
|
386
228
|
try:
|
|
387
229
|
driver_path = self._resolve_driver_name()
|
|
388
|
-
|
|
389
|
-
# Map driver paths to parameter styles
|
|
390
230
|
if "postgresql" in driver_path:
|
|
391
|
-
return (("numeric",), "numeric")
|
|
231
|
+
return (("numeric",), "numeric")
|
|
392
232
|
if "sqlite" in driver_path:
|
|
393
|
-
return (("qmark", "named_colon"), "qmark")
|
|
233
|
+
return (("qmark", "named_colon"), "qmark")
|
|
394
234
|
if "duckdb" in driver_path:
|
|
395
|
-
return (("qmark", "numeric"), "qmark")
|
|
235
|
+
return (("qmark", "numeric"), "qmark")
|
|
396
236
|
if "bigquery" in driver_path:
|
|
397
|
-
return (("named_at",), "named_at")
|
|
237
|
+
return (("named_at",), "named_at")
|
|
398
238
|
if "snowflake" in driver_path:
|
|
399
|
-
return (("qmark", "numeric"), "qmark")
|
|
239
|
+
return (("qmark", "numeric"), "qmark")
|
|
400
240
|
|
|
401
241
|
except Exception:
|
|
402
|
-
|
|
403
|
-
return (self.supported_parameter_styles, self.preferred_parameter_style)
|
|
242
|
+
logger.debug("Error resolving parameter styles for ADBC driver, using defaults")
|
|
404
243
|
return (("qmark",), "qmark")
|
|
405
244
|
|
|
406
245
|
def create_connection(self) -> AdbcConnection:
|
|
@@ -415,12 +254,10 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
|
|
|
415
254
|
|
|
416
255
|
try:
|
|
417
256
|
connect_func = self._get_connect_func()
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
if self.on_connection_create:
|
|
421
|
-
self.on_connection_create(connection)
|
|
257
|
+
connection_config_dict = self._get_connection_config_dict()
|
|
258
|
+
connection = connect_func(**connection_config_dict)
|
|
422
259
|
except Exception as e:
|
|
423
|
-
driver_name = self.driver_name
|
|
260
|
+
driver_name = self.connection_config.get("driver_name", "Unknown")
|
|
424
261
|
msg = f"Could not configure ADBC connection using driver '{driver_name}'. Error: {e}"
|
|
425
262
|
raise ImproperConfigurationError(msg) from e
|
|
426
263
|
return connection
|
|
@@ -442,11 +279,14 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
|
|
|
442
279
|
finally:
|
|
443
280
|
connection.close()
|
|
444
281
|
|
|
445
|
-
def provide_session(
|
|
282
|
+
def provide_session(
|
|
283
|
+
self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
|
|
284
|
+
) -> "AbstractContextManager[AdbcDriver]":
|
|
446
285
|
"""Provide an ADBC driver session context manager.
|
|
447
286
|
|
|
448
287
|
Args:
|
|
449
288
|
*args: Additional arguments.
|
|
289
|
+
statement_config: Optional statement configuration override.
|
|
450
290
|
**kwargs: Additional keyword arguments.
|
|
451
291
|
|
|
452
292
|
Returns:
|
|
@@ -456,41 +296,22 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
|
|
|
456
296
|
@contextmanager
|
|
457
297
|
def session_manager() -> "Generator[AdbcDriver, None, None]":
|
|
458
298
|
with self.provide_connection(*args, **kwargs) as connection:
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
if statement_config.allowed_parameter_styles is None:
|
|
467
|
-
statement_config = replace(
|
|
468
|
-
statement_config,
|
|
469
|
-
allowed_parameter_styles=supported_styles,
|
|
470
|
-
target_parameter_style=preferred_style,
|
|
471
|
-
)
|
|
472
|
-
|
|
473
|
-
driver = self.driver_type(connection=connection, config=statement_config)
|
|
474
|
-
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)
|
|
475
305
|
|
|
476
306
|
return session_manager()
|
|
477
307
|
|
|
478
|
-
|
|
479
|
-
def connection_config_dict(self) -> dict[str, Any]:
|
|
308
|
+
def _get_connection_config_dict(self) -> dict[str, Any]:
|
|
480
309
|
"""Get the connection configuration dictionary.
|
|
481
310
|
|
|
482
311
|
Returns:
|
|
483
312
|
The connection configuration dictionary.
|
|
484
313
|
"""
|
|
485
|
-
|
|
486
|
-
config = {
|
|
487
|
-
field: getattr(self, field)
|
|
488
|
-
for field in CONNECTION_FIELDS
|
|
489
|
-
if getattr(self, field, None) is not None and getattr(self, field) is not Empty
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
# Merge extras parameters
|
|
493
|
-
config.update(self.extras)
|
|
314
|
+
config = dict(self.connection_config)
|
|
494
315
|
|
|
495
316
|
if "driver_name" in config:
|
|
496
317
|
driver_name = config["driver_name"]
|
|
@@ -498,28 +319,24 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
|
|
|
498
319
|
if "uri" in config:
|
|
499
320
|
uri = config["uri"]
|
|
500
321
|
|
|
501
|
-
# SQLite: strip sqlite:// prefix
|
|
502
322
|
if driver_name in {"sqlite", "sqlite3", "adbc_driver_sqlite"} and uri.startswith("sqlite://"): # pyright: ignore
|
|
503
|
-
config["uri"] = uri[9:] #
|
|
323
|
+
config["uri"] = uri[9:] # pyright: ignore
|
|
504
324
|
|
|
505
|
-
# DuckDB: convert uri to path
|
|
506
325
|
elif driver_name in {"duckdb", "adbc_driver_duckdb"} and uri.startswith("duckdb://"): # pyright: ignore
|
|
507
|
-
config["path"] = uri[9:] #
|
|
326
|
+
config["path"] = uri[9:] # pyright: ignore
|
|
508
327
|
config.pop("uri", None)
|
|
509
328
|
|
|
510
|
-
# BigQuery: wrap certain parameters in db_kwargs
|
|
511
329
|
if driver_name in {"bigquery", "bq", "adbc_driver_bigquery"}:
|
|
512
|
-
|
|
330
|
+
bigquery_parameters = ["project_id", "dataset_id", "token"]
|
|
513
331
|
db_kwargs = config.get("db_kwargs", {})
|
|
514
332
|
|
|
515
|
-
for param in
|
|
333
|
+
for param in bigquery_parameters:
|
|
516
334
|
if param in config and param != "db_kwargs":
|
|
517
335
|
db_kwargs[param] = config.pop(param) # pyright: ignore
|
|
518
336
|
|
|
519
337
|
if db_kwargs:
|
|
520
338
|
config["db_kwargs"] = db_kwargs
|
|
521
339
|
|
|
522
|
-
# For other drivers (like PostgreSQL), merge db_kwargs into top level
|
|
523
340
|
elif "db_kwargs" in config and driver_name not in {"bigquery", "bq", "adbc_driver_bigquery"}:
|
|
524
341
|
db_kwargs = config.pop("db_kwargs")
|
|
525
342
|
if isinstance(db_kwargs, dict):
|
|
@@ -528,3 +345,17 @@ class AdbcConfig(NoPoolSyncConfig[AdbcConnection, AdbcDriver]):
|
|
|
528
345
|
config.pop("driver_name", None)
|
|
529
346
|
|
|
530
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
|