sqlspec 0.26.0__py3-none-any.whl → 0.27.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 +7 -15
- sqlspec/_serialization.py +55 -25
- sqlspec/_typing.py +62 -52
- sqlspec/adapters/adbc/_types.py +1 -1
- sqlspec/adapters/adbc/adk/__init__.py +5 -0
- sqlspec/adapters/adbc/adk/store.py +870 -0
- sqlspec/adapters/adbc/config.py +62 -12
- sqlspec/adapters/adbc/data_dictionary.py +52 -2
- sqlspec/adapters/adbc/driver.py +144 -45
- sqlspec/adapters/adbc/litestar/__init__.py +5 -0
- sqlspec/adapters/adbc/litestar/store.py +504 -0
- sqlspec/adapters/adbc/type_converter.py +44 -50
- sqlspec/adapters/aiosqlite/_types.py +1 -1
- sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/adk/store.py +527 -0
- sqlspec/adapters/aiosqlite/config.py +86 -16
- sqlspec/adapters/aiosqlite/data_dictionary.py +34 -2
- sqlspec/adapters/aiosqlite/driver.py +127 -38
- sqlspec/adapters/aiosqlite/litestar/__init__.py +5 -0
- sqlspec/adapters/aiosqlite/litestar/store.py +281 -0
- sqlspec/adapters/aiosqlite/pool.py +7 -7
- sqlspec/adapters/asyncmy/__init__.py +7 -1
- sqlspec/adapters/asyncmy/_types.py +1 -1
- sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
- sqlspec/adapters/asyncmy/adk/store.py +493 -0
- sqlspec/adapters/asyncmy/config.py +59 -17
- sqlspec/adapters/asyncmy/data_dictionary.py +41 -2
- sqlspec/adapters/asyncmy/driver.py +293 -62
- sqlspec/adapters/asyncmy/litestar/__init__.py +5 -0
- sqlspec/adapters/asyncmy/litestar/store.py +296 -0
- sqlspec/adapters/asyncpg/__init__.py +2 -1
- sqlspec/adapters/asyncpg/_type_handlers.py +71 -0
- sqlspec/adapters/asyncpg/_types.py +11 -7
- sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
- sqlspec/adapters/asyncpg/adk/store.py +450 -0
- sqlspec/adapters/asyncpg/config.py +57 -36
- sqlspec/adapters/asyncpg/data_dictionary.py +41 -2
- sqlspec/adapters/asyncpg/driver.py +153 -23
- sqlspec/adapters/asyncpg/litestar/__init__.py +5 -0
- sqlspec/adapters/asyncpg/litestar/store.py +253 -0
- sqlspec/adapters/bigquery/_types.py +1 -1
- sqlspec/adapters/bigquery/adk/__init__.py +5 -0
- sqlspec/adapters/bigquery/adk/store.py +576 -0
- sqlspec/adapters/bigquery/config.py +25 -11
- sqlspec/adapters/bigquery/data_dictionary.py +42 -2
- sqlspec/adapters/bigquery/driver.py +352 -144
- sqlspec/adapters/bigquery/litestar/__init__.py +5 -0
- sqlspec/adapters/bigquery/litestar/store.py +327 -0
- sqlspec/adapters/bigquery/type_converter.py +55 -23
- sqlspec/adapters/duckdb/_types.py +2 -2
- sqlspec/adapters/duckdb/adk/__init__.py +14 -0
- sqlspec/adapters/duckdb/adk/store.py +553 -0
- sqlspec/adapters/duckdb/config.py +79 -21
- sqlspec/adapters/duckdb/data_dictionary.py +41 -2
- sqlspec/adapters/duckdb/driver.py +138 -43
- sqlspec/adapters/duckdb/litestar/__init__.py +5 -0
- sqlspec/adapters/duckdb/litestar/store.py +332 -0
- sqlspec/adapters/duckdb/pool.py +5 -5
- sqlspec/adapters/duckdb/type_converter.py +51 -21
- sqlspec/adapters/oracledb/_numpy_handlers.py +133 -0
- sqlspec/adapters/oracledb/_types.py +20 -2
- sqlspec/adapters/oracledb/adk/__init__.py +5 -0
- sqlspec/adapters/oracledb/adk/store.py +1745 -0
- sqlspec/adapters/oracledb/config.py +120 -36
- sqlspec/adapters/oracledb/data_dictionary.py +87 -20
- sqlspec/adapters/oracledb/driver.py +292 -84
- sqlspec/adapters/oracledb/litestar/__init__.py +5 -0
- sqlspec/adapters/oracledb/litestar/store.py +767 -0
- sqlspec/adapters/oracledb/migrations.py +316 -25
- sqlspec/adapters/oracledb/type_converter.py +91 -16
- sqlspec/adapters/psqlpy/_type_handlers.py +44 -0
- sqlspec/adapters/psqlpy/_types.py +2 -1
- sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
- sqlspec/adapters/psqlpy/adk/store.py +482 -0
- sqlspec/adapters/psqlpy/config.py +45 -19
- sqlspec/adapters/psqlpy/data_dictionary.py +41 -2
- sqlspec/adapters/psqlpy/driver.py +101 -31
- sqlspec/adapters/psqlpy/litestar/__init__.py +5 -0
- sqlspec/adapters/psqlpy/litestar/store.py +272 -0
- sqlspec/adapters/psqlpy/type_converter.py +40 -11
- sqlspec/adapters/psycopg/_type_handlers.py +80 -0
- sqlspec/adapters/psycopg/_types.py +2 -1
- sqlspec/adapters/psycopg/adk/__init__.py +5 -0
- sqlspec/adapters/psycopg/adk/store.py +944 -0
- sqlspec/adapters/psycopg/config.py +65 -37
- sqlspec/adapters/psycopg/data_dictionary.py +77 -3
- sqlspec/adapters/psycopg/driver.py +200 -78
- sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
- sqlspec/adapters/psycopg/litestar/store.py +554 -0
- sqlspec/adapters/sqlite/__init__.py +2 -1
- sqlspec/adapters/sqlite/_type_handlers.py +86 -0
- sqlspec/adapters/sqlite/_types.py +1 -1
- sqlspec/adapters/sqlite/adk/__init__.py +5 -0
- sqlspec/adapters/sqlite/adk/store.py +572 -0
- sqlspec/adapters/sqlite/config.py +85 -16
- sqlspec/adapters/sqlite/data_dictionary.py +34 -2
- sqlspec/adapters/sqlite/driver.py +120 -52
- sqlspec/adapters/sqlite/litestar/__init__.py +5 -0
- sqlspec/adapters/sqlite/litestar/store.py +318 -0
- sqlspec/adapters/sqlite/pool.py +5 -5
- sqlspec/base.py +45 -26
- sqlspec/builder/__init__.py +73 -4
- sqlspec/builder/_base.py +91 -58
- sqlspec/builder/_column.py +5 -5
- sqlspec/builder/_ddl.py +98 -89
- sqlspec/builder/_delete.py +5 -4
- sqlspec/builder/_dml.py +388 -0
- sqlspec/{_sql.py → builder/_factory.py} +41 -44
- sqlspec/builder/_insert.py +5 -82
- sqlspec/builder/{mixins/_join_operations.py → _join.py} +145 -143
- sqlspec/builder/_merge.py +446 -11
- sqlspec/builder/_parsing_utils.py +9 -11
- sqlspec/builder/_select.py +1313 -25
- sqlspec/builder/_update.py +11 -42
- sqlspec/cli.py +76 -69
- sqlspec/config.py +231 -60
- sqlspec/core/__init__.py +5 -4
- sqlspec/core/cache.py +18 -18
- sqlspec/core/compiler.py +6 -8
- sqlspec/core/filters.py +37 -37
- sqlspec/core/hashing.py +9 -9
- sqlspec/core/parameters.py +76 -45
- sqlspec/core/result.py +102 -46
- sqlspec/core/splitter.py +16 -17
- sqlspec/core/statement.py +32 -31
- sqlspec/core/type_conversion.py +3 -2
- sqlspec/driver/__init__.py +1 -3
- sqlspec/driver/_async.py +95 -161
- sqlspec/driver/_common.py +133 -80
- sqlspec/driver/_sync.py +95 -162
- sqlspec/driver/mixins/_result_tools.py +20 -236
- sqlspec/driver/mixins/_sql_translator.py +4 -4
- sqlspec/exceptions.py +70 -7
- sqlspec/extensions/adk/__init__.py +53 -0
- sqlspec/extensions/adk/_types.py +51 -0
- sqlspec/extensions/adk/converters.py +172 -0
- sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +144 -0
- sqlspec/extensions/adk/migrations/__init__.py +0 -0
- sqlspec/extensions/adk/service.py +181 -0
- sqlspec/extensions/adk/store.py +536 -0
- sqlspec/extensions/aiosql/adapter.py +73 -53
- sqlspec/extensions/litestar/__init__.py +21 -4
- sqlspec/extensions/litestar/cli.py +54 -10
- sqlspec/extensions/litestar/config.py +59 -266
- sqlspec/extensions/litestar/handlers.py +46 -17
- sqlspec/extensions/litestar/migrations/0001_create_session_table.py +137 -0
- sqlspec/extensions/litestar/migrations/__init__.py +3 -0
- sqlspec/extensions/litestar/plugin.py +324 -223
- sqlspec/extensions/litestar/providers.py +25 -25
- sqlspec/extensions/litestar/store.py +265 -0
- sqlspec/loader.py +30 -49
- sqlspec/migrations/base.py +200 -76
- sqlspec/migrations/commands.py +591 -62
- sqlspec/migrations/context.py +6 -9
- sqlspec/migrations/fix.py +199 -0
- sqlspec/migrations/loaders.py +47 -19
- sqlspec/migrations/runner.py +241 -75
- sqlspec/migrations/tracker.py +237 -21
- sqlspec/migrations/utils.py +51 -3
- sqlspec/migrations/validation.py +177 -0
- sqlspec/protocols.py +66 -36
- sqlspec/storage/_utils.py +98 -0
- sqlspec/storage/backends/fsspec.py +134 -106
- sqlspec/storage/backends/local.py +78 -51
- sqlspec/storage/backends/obstore.py +278 -162
- sqlspec/storage/registry.py +75 -39
- sqlspec/typing.py +14 -84
- sqlspec/utils/config_resolver.py +6 -6
- sqlspec/utils/correlation.py +4 -5
- sqlspec/utils/data_transformation.py +3 -2
- sqlspec/utils/deprecation.py +9 -8
- sqlspec/utils/fixtures.py +4 -4
- sqlspec/utils/logging.py +46 -6
- sqlspec/utils/module_loader.py +2 -2
- sqlspec/utils/schema.py +288 -0
- sqlspec/utils/serializers.py +3 -3
- sqlspec/utils/sync_tools.py +21 -17
- sqlspec/utils/text.py +1 -2
- sqlspec/utils/type_guards.py +111 -20
- sqlspec/utils/version.py +433 -0
- {sqlspec-0.26.0.dist-info → sqlspec-0.27.0.dist-info}/METADATA +40 -21
- sqlspec-0.27.0.dist-info/RECORD +207 -0
- sqlspec/builder/mixins/__init__.py +0 -55
- sqlspec/builder/mixins/_cte_and_set_ops.py +0 -253
- sqlspec/builder/mixins/_delete_operations.py +0 -50
- sqlspec/builder/mixins/_insert_operations.py +0 -282
- sqlspec/builder/mixins/_merge_operations.py +0 -698
- sqlspec/builder/mixins/_order_limit_operations.py +0 -145
- sqlspec/builder/mixins/_pivot_operations.py +0 -157
- sqlspec/builder/mixins/_select_operations.py +0 -930
- sqlspec/builder/mixins/_update_operations.py +0 -199
- sqlspec/builder/mixins/_where_clause.py +0 -1298
- sqlspec-0.26.0.dist-info/RECORD +0 -157
- sqlspec-0.26.0.dist-info/licenses/NOTICE +0 -29
- {sqlspec-0.26.0.dist-info → sqlspec-0.27.0.dist-info}/WHEEL +0 -0
- {sqlspec-0.26.0.dist-info → sqlspec-0.27.0.dist-info}/entry_points.txt +0 -0
- {sqlspec-0.26.0.dist-info → sqlspec-0.27.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import contextlib
|
|
4
4
|
import logging
|
|
5
5
|
from contextlib import asynccontextmanager
|
|
6
|
-
from typing import TYPE_CHECKING, Any, ClassVar,
|
|
6
|
+
from typing import TYPE_CHECKING, Any, ClassVar, TypedDict, cast
|
|
7
7
|
|
|
8
8
|
from psycopg.rows import dict_row
|
|
9
9
|
from psycopg_pool import AsyncConnectionPool, ConnectionPool
|
|
@@ -18,6 +18,7 @@ from sqlspec.adapters.psycopg.driver import (
|
|
|
18
18
|
psycopg_statement_config,
|
|
19
19
|
)
|
|
20
20
|
from sqlspec.config import AsyncDatabaseConfig, SyncDatabaseConfig
|
|
21
|
+
from sqlspec.typing import PGVECTOR_INSTALLED
|
|
21
22
|
|
|
22
23
|
if TYPE_CHECKING:
|
|
23
24
|
from collections.abc import AsyncGenerator, Callable, Generator
|
|
@@ -28,7 +29,7 @@ if TYPE_CHECKING:
|
|
|
28
29
|
logger = logging.getLogger("sqlspec.adapters.psycopg")
|
|
29
30
|
|
|
30
31
|
|
|
31
|
-
class PsycopgConnectionParams(TypedDict
|
|
32
|
+
class PsycopgConnectionParams(TypedDict):
|
|
32
33
|
"""Psycopg connection parameters."""
|
|
33
34
|
|
|
34
35
|
conninfo: NotRequired[str]
|
|
@@ -48,7 +49,7 @@ class PsycopgConnectionParams(TypedDict, total=False):
|
|
|
48
49
|
extra: NotRequired[dict[str, Any]]
|
|
49
50
|
|
|
50
51
|
|
|
51
|
-
class PsycopgPoolParams(PsycopgConnectionParams
|
|
52
|
+
class PsycopgPoolParams(PsycopgConnectionParams):
|
|
52
53
|
"""Psycopg pool parameters."""
|
|
53
54
|
|
|
54
55
|
min_size: NotRequired[int]
|
|
@@ -64,10 +65,25 @@ class PsycopgPoolParams(PsycopgConnectionParams, total=False):
|
|
|
64
65
|
kwargs: NotRequired[dict[str, Any]]
|
|
65
66
|
|
|
66
67
|
|
|
68
|
+
class PsycopgDriverFeatures(TypedDict):
|
|
69
|
+
"""Psycopg driver feature flags.
|
|
70
|
+
|
|
71
|
+
enable_pgvector: Enable automatic pgvector extension support for vector similarity search.
|
|
72
|
+
Requires pgvector-python package (pip install pgvector) and PostgreSQL with pgvector extension.
|
|
73
|
+
Defaults to True when pgvector-python is installed.
|
|
74
|
+
Provides automatic conversion between Python objects and PostgreSQL vector types.
|
|
75
|
+
Enables vector similarity operations and index support.
|
|
76
|
+
Set to False to disable pgvector support even when package is available.
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
enable_pgvector: NotRequired[bool]
|
|
80
|
+
|
|
81
|
+
|
|
67
82
|
__all__ = (
|
|
68
83
|
"PsycopgAsyncConfig",
|
|
69
84
|
"PsycopgAsyncCursor",
|
|
70
85
|
"PsycopgConnectionParams",
|
|
86
|
+
"PsycopgDriverFeatures",
|
|
71
87
|
"PsycopgPoolParams",
|
|
72
88
|
"PsycopgSyncConfig",
|
|
73
89
|
"PsycopgSyncCursor",
|
|
@@ -79,16 +95,18 @@ class PsycopgSyncConfig(SyncDatabaseConfig[PsycopgSyncConnection, ConnectionPool
|
|
|
79
95
|
|
|
80
96
|
driver_type: "ClassVar[type[PsycopgSyncDriver]]" = PsycopgSyncDriver
|
|
81
97
|
connection_type: "ClassVar[type[PsycopgSyncConnection]]" = PsycopgSyncConnection
|
|
98
|
+
supports_transactional_ddl: "ClassVar[bool]" = True
|
|
82
99
|
|
|
83
100
|
def __init__(
|
|
84
101
|
self,
|
|
85
102
|
*,
|
|
86
|
-
pool_config: "
|
|
87
|
-
pool_instance:
|
|
88
|
-
migration_config:
|
|
89
|
-
statement_config: "
|
|
90
|
-
driver_features: "
|
|
91
|
-
bind_key: "
|
|
103
|
+
pool_config: "PsycopgPoolParams | dict[str, Any] | None" = None,
|
|
104
|
+
pool_instance: "ConnectionPool | None" = None,
|
|
105
|
+
migration_config: dict[str, Any] | None = None,
|
|
106
|
+
statement_config: "StatementConfig | None" = None,
|
|
107
|
+
driver_features: "dict[str, Any] | None" = None,
|
|
108
|
+
bind_key: "str | None" = None,
|
|
109
|
+
extension_config: "dict[str, dict[str, Any]] | None" = None,
|
|
92
110
|
) -> None:
|
|
93
111
|
"""Initialize Psycopg synchronous configuration.
|
|
94
112
|
|
|
@@ -99,19 +117,26 @@ class PsycopgSyncConfig(SyncDatabaseConfig[PsycopgSyncConnection, ConnectionPool
|
|
|
99
117
|
statement_config: Default SQL statement configuration
|
|
100
118
|
driver_features: Optional driver feature configuration
|
|
101
119
|
bind_key: Optional unique identifier for this configuration
|
|
120
|
+
extension_config: Extension-specific configuration (e.g., Litestar plugin settings)
|
|
102
121
|
"""
|
|
103
122
|
processed_pool_config: dict[str, Any] = dict(pool_config) if pool_config else {}
|
|
104
123
|
if "extra" in processed_pool_config:
|
|
105
124
|
extras = processed_pool_config.pop("extra")
|
|
106
125
|
processed_pool_config.update(extras)
|
|
107
126
|
|
|
127
|
+
if driver_features is None:
|
|
128
|
+
driver_features = {}
|
|
129
|
+
if "enable_pgvector" not in driver_features:
|
|
130
|
+
driver_features["enable_pgvector"] = PGVECTOR_INSTALLED
|
|
131
|
+
|
|
108
132
|
super().__init__(
|
|
109
133
|
pool_config=processed_pool_config,
|
|
110
134
|
pool_instance=pool_instance,
|
|
111
135
|
migration_config=migration_config,
|
|
112
136
|
statement_config=statement_config or psycopg_statement_config,
|
|
113
|
-
driver_features=driver_features
|
|
137
|
+
driver_features=driver_features,
|
|
114
138
|
bind_key=bind_key,
|
|
139
|
+
extension_config=extension_config,
|
|
115
140
|
)
|
|
116
141
|
|
|
117
142
|
def _create_pool(self) -> "ConnectionPool":
|
|
@@ -140,15 +165,10 @@ class PsycopgSyncConfig(SyncDatabaseConfig[PsycopgSyncConnection, ConnectionPool
|
|
|
140
165
|
if autocommit_setting is not None:
|
|
141
166
|
conn.autocommit = autocommit_setting
|
|
142
167
|
|
|
143
|
-
|
|
144
|
-
|
|
168
|
+
if self.driver_features.get("enable_pgvector", False):
|
|
169
|
+
from sqlspec.adapters.psycopg._type_handlers import register_pgvector_sync
|
|
145
170
|
|
|
146
|
-
|
|
147
|
-
logger.debug("pgvector registered successfully for psycopg sync connection")
|
|
148
|
-
except ImportError:
|
|
149
|
-
pass
|
|
150
|
-
except Exception as e:
|
|
151
|
-
logger.debug("Failed to register pgvector for psycopg sync: %s", e)
|
|
171
|
+
register_pgvector_sync(conn)
|
|
152
172
|
|
|
153
173
|
pool_parameters["configure"] = all_config.pop("configure", configure_connection)
|
|
154
174
|
|
|
@@ -219,7 +239,7 @@ class PsycopgSyncConfig(SyncDatabaseConfig[PsycopgSyncConnection, ConnectionPool
|
|
|
219
239
|
|
|
220
240
|
@contextlib.contextmanager
|
|
221
241
|
def provide_session(
|
|
222
|
-
self, *args: Any, statement_config: "
|
|
242
|
+
self, *args: Any, statement_config: "StatementConfig | None" = None, **kwargs: Any
|
|
223
243
|
) -> "Generator[PsycopgSyncDriver, None, None]":
|
|
224
244
|
"""Provide a driver session context manager.
|
|
225
245
|
|
|
@@ -233,7 +253,9 @@ class PsycopgSyncConfig(SyncDatabaseConfig[PsycopgSyncConnection, ConnectionPool
|
|
|
233
253
|
"""
|
|
234
254
|
with self.provide_connection(*args, **kwargs) as conn:
|
|
235
255
|
final_statement_config = statement_config or self.statement_config
|
|
236
|
-
yield self.driver_type(
|
|
256
|
+
yield self.driver_type(
|
|
257
|
+
connection=conn, statement_config=final_statement_config, driver_features=self.driver_features
|
|
258
|
+
)
|
|
237
259
|
|
|
238
260
|
def provide_pool(self, *args: Any, **kwargs: Any) -> "ConnectionPool":
|
|
239
261
|
"""Provide pool instance.
|
|
@@ -264,16 +286,18 @@ class PsycopgAsyncConfig(AsyncDatabaseConfig[PsycopgAsyncConnection, AsyncConnec
|
|
|
264
286
|
|
|
265
287
|
driver_type: ClassVar[type[PsycopgAsyncDriver]] = PsycopgAsyncDriver
|
|
266
288
|
connection_type: "ClassVar[type[PsycopgAsyncConnection]]" = PsycopgAsyncConnection
|
|
289
|
+
supports_transactional_ddl: "ClassVar[bool]" = True
|
|
267
290
|
|
|
268
291
|
def __init__(
|
|
269
292
|
self,
|
|
270
293
|
*,
|
|
271
|
-
pool_config: "
|
|
272
|
-
pool_instance: "
|
|
273
|
-
migration_config: "
|
|
274
|
-
statement_config: "
|
|
275
|
-
driver_features: "
|
|
276
|
-
bind_key: "
|
|
294
|
+
pool_config: "PsycopgPoolParams | dict[str, Any] | None" = None,
|
|
295
|
+
pool_instance: "AsyncConnectionPool | None" = None,
|
|
296
|
+
migration_config: "dict[str, Any] | None" = None,
|
|
297
|
+
statement_config: "StatementConfig | None" = None,
|
|
298
|
+
driver_features: "dict[str, Any] | None" = None,
|
|
299
|
+
bind_key: "str | None" = None,
|
|
300
|
+
extension_config: "dict[str, dict[str, Any]] | None" = None,
|
|
277
301
|
) -> None:
|
|
278
302
|
"""Initialize Psycopg asynchronous configuration.
|
|
279
303
|
|
|
@@ -284,19 +308,26 @@ class PsycopgAsyncConfig(AsyncDatabaseConfig[PsycopgAsyncConnection, AsyncConnec
|
|
|
284
308
|
statement_config: Default SQL statement configuration
|
|
285
309
|
driver_features: Optional driver feature configuration
|
|
286
310
|
bind_key: Optional unique identifier for this configuration
|
|
311
|
+
extension_config: Extension-specific configuration (e.g., Litestar plugin settings)
|
|
287
312
|
"""
|
|
288
313
|
processed_pool_config: dict[str, Any] = dict(pool_config) if pool_config else {}
|
|
289
314
|
if "extra" in processed_pool_config:
|
|
290
315
|
extras = processed_pool_config.pop("extra")
|
|
291
316
|
processed_pool_config.update(extras)
|
|
292
317
|
|
|
318
|
+
if driver_features is None:
|
|
319
|
+
driver_features = {}
|
|
320
|
+
if "enable_pgvector" not in driver_features:
|
|
321
|
+
driver_features["enable_pgvector"] = PGVECTOR_INSTALLED
|
|
322
|
+
|
|
293
323
|
super().__init__(
|
|
294
324
|
pool_config=processed_pool_config,
|
|
295
325
|
pool_instance=pool_instance,
|
|
296
326
|
migration_config=migration_config,
|
|
297
327
|
statement_config=statement_config or psycopg_statement_config,
|
|
298
|
-
driver_features=driver_features
|
|
328
|
+
driver_features=driver_features,
|
|
299
329
|
bind_key=bind_key,
|
|
330
|
+
extension_config=extension_config,
|
|
300
331
|
)
|
|
301
332
|
|
|
302
333
|
async def _create_pool(self) -> "AsyncConnectionPool":
|
|
@@ -323,15 +354,10 @@ class PsycopgAsyncConfig(AsyncDatabaseConfig[PsycopgAsyncConnection, AsyncConnec
|
|
|
323
354
|
if autocommit_setting is not None:
|
|
324
355
|
await conn.set_autocommit(autocommit_setting)
|
|
325
356
|
|
|
326
|
-
|
|
327
|
-
from
|
|
357
|
+
if self.driver_features.get("enable_pgvector", False):
|
|
358
|
+
from sqlspec.adapters.psycopg._type_handlers import register_pgvector_async
|
|
328
359
|
|
|
329
|
-
await
|
|
330
|
-
logger.debug("pgvector registered successfully for psycopg async connection")
|
|
331
|
-
except ImportError:
|
|
332
|
-
pass
|
|
333
|
-
except Exception as e:
|
|
334
|
-
logger.debug("Failed to register pgvector for psycopg async: %s", e)
|
|
360
|
+
await register_pgvector_async(conn)
|
|
335
361
|
|
|
336
362
|
pool_parameters["configure"] = all_config.pop("configure", configure_connection)
|
|
337
363
|
|
|
@@ -394,7 +420,7 @@ class PsycopgAsyncConfig(AsyncDatabaseConfig[PsycopgAsyncConnection, AsyncConnec
|
|
|
394
420
|
|
|
395
421
|
@asynccontextmanager
|
|
396
422
|
async def provide_session(
|
|
397
|
-
self, *args: Any, statement_config: "
|
|
423
|
+
self, *args: Any, statement_config: "StatementConfig | None" = None, **kwargs: Any
|
|
398
424
|
) -> "AsyncGenerator[PsycopgAsyncDriver, None]":
|
|
399
425
|
"""Provide an async driver session context manager.
|
|
400
426
|
|
|
@@ -408,7 +434,9 @@ class PsycopgAsyncConfig(AsyncDatabaseConfig[PsycopgAsyncConnection, AsyncConnec
|
|
|
408
434
|
"""
|
|
409
435
|
async with self.provide_connection(*args, **kwargs) as conn:
|
|
410
436
|
final_statement_config = statement_config or psycopg_statement_config
|
|
411
|
-
yield self.driver_type(
|
|
437
|
+
yield self.driver_type(
|
|
438
|
+
connection=conn, statement_config=final_statement_config, driver_features=self.driver_features
|
|
439
|
+
)
|
|
412
440
|
|
|
413
441
|
async def provide_pool(self, *args: Any, **kwargs: Any) -> "AsyncConnectionPool":
|
|
414
442
|
"""Provide async pool instance.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""PostgreSQL-specific data dictionary for metadata queries via psycopg."""
|
|
2
2
|
|
|
3
3
|
import re
|
|
4
|
-
from typing import TYPE_CHECKING,
|
|
4
|
+
from typing import TYPE_CHECKING, Any, cast
|
|
5
5
|
|
|
6
6
|
from sqlspec.driver import (
|
|
7
7
|
AsyncDataDictionaryBase,
|
|
@@ -28,7 +28,7 @@ __all__ = ("PostgresAsyncDataDictionary", "PostgresSyncDataDictionary")
|
|
|
28
28
|
class PostgresSyncDataDictionary(SyncDataDictionaryBase):
|
|
29
29
|
"""PostgreSQL-specific sync data dictionary."""
|
|
30
30
|
|
|
31
|
-
def get_version(self, driver: SyncDriverAdapterBase) -> "
|
|
31
|
+
def get_version(self, driver: SyncDriverAdapterBase) -> "VersionInfo | None":
|
|
32
32
|
"""Get PostgreSQL database version information.
|
|
33
33
|
|
|
34
34
|
Args:
|
|
@@ -119,6 +119,43 @@ class PostgresSyncDataDictionary(SyncDataDictionaryBase):
|
|
|
119
119
|
}
|
|
120
120
|
return type_map.get(type_category, "TEXT")
|
|
121
121
|
|
|
122
|
+
def get_columns(
|
|
123
|
+
self, driver: SyncDriverAdapterBase, table: str, schema: "str | None" = None
|
|
124
|
+
) -> "list[dict[str, Any]]":
|
|
125
|
+
"""Get column information for a table using information_schema.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
driver: Psycopg sync driver instance
|
|
129
|
+
table: Table name to query columns for
|
|
130
|
+
schema: Schema name (None for default 'public')
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
List of column metadata dictionaries with keys:
|
|
134
|
+
- column_name: Name of the column
|
|
135
|
+
- data_type: PostgreSQL data type
|
|
136
|
+
- is_nullable: Whether column allows NULL (YES/NO)
|
|
137
|
+
- column_default: Default value if any
|
|
138
|
+
"""
|
|
139
|
+
psycopg_driver = cast("PsycopgSyncDriver", driver)
|
|
140
|
+
|
|
141
|
+
if schema:
|
|
142
|
+
sql = f"""
|
|
143
|
+
SELECT column_name, data_type, is_nullable, column_default
|
|
144
|
+
FROM information_schema.columns
|
|
145
|
+
WHERE table_name = '{table}' AND table_schema = '{schema}'
|
|
146
|
+
ORDER BY ordinal_position
|
|
147
|
+
"""
|
|
148
|
+
else:
|
|
149
|
+
sql = f"""
|
|
150
|
+
SELECT column_name, data_type, is_nullable, column_default
|
|
151
|
+
FROM information_schema.columns
|
|
152
|
+
WHERE table_name = '{table}' AND table_schema = 'public'
|
|
153
|
+
ORDER BY ordinal_position
|
|
154
|
+
"""
|
|
155
|
+
|
|
156
|
+
result = psycopg_driver.execute(sql)
|
|
157
|
+
return result.data or []
|
|
158
|
+
|
|
122
159
|
def list_available_features(self) -> "list[str]":
|
|
123
160
|
"""List available PostgreSQL feature flags.
|
|
124
161
|
|
|
@@ -144,7 +181,7 @@ class PostgresSyncDataDictionary(SyncDataDictionaryBase):
|
|
|
144
181
|
class PostgresAsyncDataDictionary(AsyncDataDictionaryBase):
|
|
145
182
|
"""PostgreSQL-specific async data dictionary."""
|
|
146
183
|
|
|
147
|
-
async def get_version(self, driver: AsyncDriverAdapterBase) -> "
|
|
184
|
+
async def get_version(self, driver: AsyncDriverAdapterBase) -> "VersionInfo | None":
|
|
148
185
|
"""Get PostgreSQL database version information.
|
|
149
186
|
|
|
150
187
|
Args:
|
|
@@ -235,6 +272,43 @@ class PostgresAsyncDataDictionary(AsyncDataDictionaryBase):
|
|
|
235
272
|
}
|
|
236
273
|
return type_map.get(type_category, "TEXT")
|
|
237
274
|
|
|
275
|
+
async def get_columns(
|
|
276
|
+
self, driver: AsyncDriverAdapterBase, table: str, schema: "str | None" = None
|
|
277
|
+
) -> "list[dict[str, Any]]":
|
|
278
|
+
"""Get column information for a table using information_schema.
|
|
279
|
+
|
|
280
|
+
Args:
|
|
281
|
+
driver: Psycopg async driver instance
|
|
282
|
+
table: Table name to query columns for
|
|
283
|
+
schema: Schema name (None for default 'public')
|
|
284
|
+
|
|
285
|
+
Returns:
|
|
286
|
+
List of column metadata dictionaries with keys:
|
|
287
|
+
- column_name: Name of the column
|
|
288
|
+
- data_type: PostgreSQL data type
|
|
289
|
+
- is_nullable: Whether column allows NULL (YES/NO)
|
|
290
|
+
- column_default: Default value if any
|
|
291
|
+
"""
|
|
292
|
+
psycopg_driver = cast("PsycopgAsyncDriver", driver)
|
|
293
|
+
|
|
294
|
+
if schema:
|
|
295
|
+
sql = f"""
|
|
296
|
+
SELECT column_name, data_type, is_nullable, column_default
|
|
297
|
+
FROM information_schema.columns
|
|
298
|
+
WHERE table_name = '{table}' AND table_schema = '{schema}'
|
|
299
|
+
ORDER BY ordinal_position
|
|
300
|
+
"""
|
|
301
|
+
else:
|
|
302
|
+
sql = f"""
|
|
303
|
+
SELECT column_name, data_type, is_nullable, column_default
|
|
304
|
+
FROM information_schema.columns
|
|
305
|
+
WHERE table_name = '{table}' AND table_schema = 'public'
|
|
306
|
+
ORDER BY ordinal_position
|
|
307
|
+
"""
|
|
308
|
+
|
|
309
|
+
result = await psycopg_driver.execute(sql)
|
|
310
|
+
return result.data or []
|
|
311
|
+
|
|
238
312
|
def list_available_features(self) -> "list[str]":
|
|
239
313
|
"""List available PostgreSQL feature flags.
|
|
240
314
|
|