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/storage/registry.py
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
"""Unified Storage Registry for ObjectStore backends.
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
-
|
|
6
|
-
- Intelligent scheme-based routing with dependency detection
|
|
7
|
-
- Named aliases for commonly used configurations (secondary feature)
|
|
8
|
-
- Automatic instrumentation integration
|
|
3
|
+
Provides a flexible, lazy-loading storage registry that supports URI-first access
|
|
4
|
+
pattern with automatic backend detection, ObStore preferred with FSSpec fallback,
|
|
5
|
+
intelligent scheme-based routing, and named aliases for common configurations.
|
|
9
6
|
"""
|
|
10
7
|
|
|
11
8
|
import logging
|
|
9
|
+
import re
|
|
12
10
|
from pathlib import Path
|
|
13
|
-
from typing import Any,
|
|
11
|
+
from typing import Any, Final, Optional, Union, cast
|
|
12
|
+
|
|
13
|
+
from mypy_extensions import mypyc_attr
|
|
14
14
|
|
|
15
15
|
from sqlspec.exceptions import ImproperConfigurationError, MissingDependencyError
|
|
16
16
|
from sqlspec.protocols import ObjectStoreProtocol
|
|
@@ -21,28 +21,27 @@ __all__ = ("StorageRegistry", "storage_registry")
|
|
|
21
21
|
|
|
22
22
|
logger = logging.getLogger(__name__)
|
|
23
23
|
|
|
24
|
-
BackendT = TypeVar("BackendT", bound=ObjectStoreProtocol)
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
SCHEME_REGEX: Final = re.compile(r"([a-zA-Z0-9+.-]+)://")
|
|
26
|
+
FILE_PROTOCOL: Final[str] = "file"
|
|
27
|
+
S3_PROTOCOL: Final[str] = "s3"
|
|
28
|
+
GCS_PROTOCOL: Final[str] = "gs"
|
|
29
|
+
AZURE_PROTOCOL: Final[str] = "az"
|
|
30
|
+
FSSPEC_ONLY_SCHEMES: Final[frozenset[str]] = frozenset({"http", "https", "ftp", "sftp", "ssh"})
|
|
27
31
|
|
|
28
32
|
|
|
33
|
+
@mypyc_attr(allow_interpreted_subclasses=True)
|
|
29
34
|
class StorageRegistry:
|
|
30
|
-
"""
|
|
35
|
+
"""Storage registry with URI-first access and automatic backend selection.
|
|
31
36
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- Automatic ObStore preference when available
|
|
35
|
-
- Intelligent FSSpec fallback for unsupported schemes or when ObStore unavailable
|
|
36
|
-
- Named aliases as secondary feature for commonly used configurations
|
|
37
|
-
- Dependency-aware backend selection with clear error messages
|
|
37
|
+
Provides URI-first access pattern with automatic backend selection.
|
|
38
|
+
Named aliases support complex configurations.
|
|
38
39
|
|
|
39
40
|
Examples:
|
|
40
|
-
|
|
41
|
-
backend = registry.get("
|
|
42
|
-
backend = registry.get("
|
|
43
|
-
backend = registry.get("gs://bucket/data.json") # ObStore for GCS
|
|
41
|
+
backend = registry.get("s3://my-bucket/file.parquet")
|
|
42
|
+
backend = registry.get("file:///tmp/data.csv")
|
|
43
|
+
backend = registry.get("gs://bucket/data.json")
|
|
44
44
|
|
|
45
|
-
# Secondary usage: Named aliases for complex configurations
|
|
46
45
|
registry.register_alias(
|
|
47
46
|
"production-s3",
|
|
48
47
|
uri="s3://prod-bucket/data",
|
|
@@ -50,17 +49,16 @@ class StorageRegistry:
|
|
|
50
49
|
aws_access_key_id="...",
|
|
51
50
|
aws_secret_access_key="..."
|
|
52
51
|
)
|
|
53
|
-
backend = registry.get("production-s3")
|
|
54
|
-
|
|
55
|
-
# Automatic fallback when ObStore unavailable
|
|
56
|
-
# If obstore not installed: s3:// → FSSpec automatically
|
|
57
|
-
# Clear error if neither backend supports the scheme
|
|
52
|
+
backend = registry.get("production-s3")
|
|
58
53
|
"""
|
|
59
54
|
|
|
55
|
+
__slots__ = ("_alias_configs", "_aliases", "_cache", "_instances")
|
|
56
|
+
|
|
60
57
|
def __init__(self) -> None:
|
|
61
58
|
self._alias_configs: dict[str, tuple[type[ObjectStoreProtocol], str, dict[str, Any]]] = {}
|
|
62
59
|
self._aliases: dict[str, dict[str, Any]] = {}
|
|
63
60
|
self._instances: dict[Union[str, tuple[str, tuple[tuple[str, Any], ...]]], ObjectStoreProtocol] = {}
|
|
61
|
+
self._cache: dict[str, tuple[str, type[ObjectStoreProtocol]]] = {}
|
|
64
62
|
|
|
65
63
|
def register_alias(
|
|
66
64
|
self,
|
|
@@ -87,26 +85,23 @@ class StorageRegistry:
|
|
|
87
85
|
|
|
88
86
|
config = config or {}
|
|
89
87
|
config.update(kwargs)
|
|
90
|
-
|
|
91
88
|
backend_config = dict(config)
|
|
92
89
|
if base_path:
|
|
93
90
|
backend_config["base_path"] = base_path
|
|
94
|
-
|
|
95
91
|
self._alias_configs[alias] = (backend, uri, backend_config)
|
|
96
|
-
|
|
97
92
|
test_config = dict(backend_config)
|
|
98
93
|
test_config["uri"] = uri
|
|
99
94
|
self._aliases[alias] = test_config
|
|
100
95
|
|
|
101
96
|
def get(self, uri_or_alias: Union[str, Path], **kwargs: Any) -> ObjectStoreProtocol:
|
|
102
|
-
"""Get backend instance using URI-first routing with
|
|
97
|
+
"""Get backend instance using URI-first routing with automatic backend selection.
|
|
103
98
|
|
|
104
99
|
Args:
|
|
105
|
-
uri_or_alias: URI to resolve directly OR named alias
|
|
100
|
+
uri_or_alias: URI to resolve directly OR named alias
|
|
106
101
|
**kwargs: Additional backend-specific configuration options
|
|
107
102
|
|
|
108
103
|
Returns:
|
|
109
|
-
Backend instance with automatic
|
|
104
|
+
Backend instance with automatic backend selection
|
|
110
105
|
|
|
111
106
|
Raises:
|
|
112
107
|
ImproperConfigurationError: If alias not found or invalid input
|
|
@@ -121,83 +116,58 @@ class StorageRegistry:
|
|
|
121
116
|
cache_key = (uri_or_alias, tuple(sorted(kwargs.items()))) if kwargs else uri_or_alias
|
|
122
117
|
if cache_key in self._instances:
|
|
123
118
|
return self._instances[cache_key]
|
|
124
|
-
|
|
125
|
-
if
|
|
119
|
+
scheme = self._get_scheme(uri_or_alias)
|
|
120
|
+
if not scheme and (
|
|
121
|
+
Path(uri_or_alias).exists()
|
|
122
|
+
or Path(uri_or_alias).is_absolute()
|
|
123
|
+
or uri_or_alias.startswith(("~", "."))
|
|
124
|
+
or ":\\" in uri_or_alias
|
|
125
|
+
or "/" in uri_or_alias
|
|
126
|
+
):
|
|
127
|
+
scheme = "file"
|
|
128
|
+
uri_or_alias = f"file://{uri_or_alias}"
|
|
129
|
+
|
|
130
|
+
if scheme:
|
|
126
131
|
instance = self._resolve_from_uri(uri_or_alias, **kwargs)
|
|
127
132
|
elif uri_or_alias in self._alias_configs:
|
|
128
133
|
backend_cls, stored_uri, config = self._alias_configs[uri_or_alias]
|
|
129
|
-
|
|
130
|
-
instance = backend_cls(stored_uri, **merged_config)
|
|
134
|
+
instance = backend_cls(stored_uri, **{**config, **kwargs})
|
|
131
135
|
else:
|
|
132
136
|
msg = f"Unknown storage alias or invalid URI: '{uri_or_alias}'"
|
|
133
137
|
raise ImproperConfigurationError(msg)
|
|
134
|
-
|
|
135
138
|
self._instances[cache_key] = instance
|
|
136
139
|
return instance
|
|
137
140
|
|
|
138
141
|
def _resolve_from_uri(self, uri: str, **kwargs: Any) -> ObjectStoreProtocol:
|
|
139
142
|
"""Resolve backend from URI, trying ObStore first, then FSSpec."""
|
|
140
143
|
scheme = self._get_scheme(uri)
|
|
141
|
-
last_exc: Optional[Exception] = None
|
|
142
|
-
|
|
143
144
|
if scheme not in FSSPEC_ONLY_SCHEMES and OBSTORE_INSTALLED:
|
|
144
145
|
try:
|
|
145
146
|
return self._create_backend("obstore", uri, **kwargs)
|
|
146
|
-
except (ImportError,
|
|
147
|
-
|
|
148
|
-
last_exc = e
|
|
149
|
-
|
|
147
|
+
except (ValueError, ImportError, NotImplementedError):
|
|
148
|
+
pass
|
|
150
149
|
if FSSPEC_INSTALLED:
|
|
151
150
|
try:
|
|
152
151
|
return self._create_backend("fsspec", uri, **kwargs)
|
|
153
|
-
except (ImportError,
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
msg = f"No storage backend available for URI '{uri}'. Install 'obstore' or 'fsspec' and required dependencies."
|
|
158
|
-
raise MissingDependencyError(msg) from last_exc
|
|
152
|
+
except (ValueError, ImportError, NotImplementedError):
|
|
153
|
+
pass
|
|
154
|
+
msg = f"No storage backend available for scheme '{scheme}'. Install obstore or fsspec."
|
|
155
|
+
raise MissingDependencyError(msg)
|
|
159
156
|
|
|
160
157
|
def _determine_backend_class(self, uri: str) -> type[ObjectStoreProtocol]:
|
|
161
|
-
"""Determine the
|
|
162
|
-
|
|
163
|
-
Prefers ObStore for its superior performance and native capabilities,
|
|
164
|
-
falls back to FSSpec for extended protocol support.
|
|
165
|
-
|
|
166
|
-
Args:
|
|
167
|
-
uri: URI to determine backend for.
|
|
168
|
-
|
|
169
|
-
Returns:
|
|
170
|
-
Backend class (not instance)
|
|
171
|
-
"""
|
|
158
|
+
"""Determine the backend class for a URI based on availability."""
|
|
172
159
|
scheme = self._get_scheme(uri)
|
|
173
|
-
|
|
174
|
-
# Check if scheme requires FSSpec (not supported by ObStore)
|
|
175
160
|
if scheme in FSSPEC_ONLY_SCHEMES and FSSPEC_INSTALLED:
|
|
176
161
|
return self._get_backend_class("fsspec")
|
|
177
|
-
|
|
178
|
-
# Prefer ObStore for its superior performance
|
|
179
162
|
if OBSTORE_INSTALLED:
|
|
180
163
|
return self._get_backend_class("obstore")
|
|
181
|
-
# Could check capabilities here if needed
|
|
182
|
-
|
|
183
164
|
if FSSPEC_INSTALLED:
|
|
184
165
|
return self._get_backend_class("fsspec")
|
|
185
|
-
|
|
186
166
|
msg = f"No backend available for URI scheme '{scheme}'. Install obstore or fsspec."
|
|
187
167
|
raise MissingDependencyError(msg)
|
|
188
168
|
|
|
189
169
|
def _get_backend_class(self, backend_type: str) -> type[ObjectStoreProtocol]:
|
|
190
|
-
"""Get backend class by type name.
|
|
191
|
-
|
|
192
|
-
Args:
|
|
193
|
-
backend_type: Backend type ('obstore' or 'fsspec')
|
|
194
|
-
|
|
195
|
-
Returns:
|
|
196
|
-
Backend class
|
|
197
|
-
|
|
198
|
-
Raises:
|
|
199
|
-
ValueError: If unknown backend type
|
|
200
|
-
"""
|
|
170
|
+
"""Get backend class by type name."""
|
|
201
171
|
if backend_type == "obstore":
|
|
202
172
|
from sqlspec.storage.backends.obstore import ObStoreBackend
|
|
203
173
|
|
|
@@ -211,16 +181,15 @@ class StorageRegistry:
|
|
|
211
181
|
|
|
212
182
|
def _create_backend(self, backend_type: str, uri: str, **kwargs: Any) -> ObjectStoreProtocol:
|
|
213
183
|
"""Create backend instance for URI."""
|
|
214
|
-
|
|
215
|
-
return backend_cls(uri, **kwargs)
|
|
184
|
+
return self._get_backend_class(backend_type)(uri, **kwargs)
|
|
216
185
|
|
|
217
|
-
def _get_scheme(self, uri: str) -> str:
|
|
218
|
-
"""Extract scheme from URI."""
|
|
219
|
-
if not uri
|
|
220
|
-
return
|
|
221
|
-
|
|
186
|
+
def _get_scheme(self, uri: str) -> Optional[str]:
|
|
187
|
+
"""Extract the scheme from a URI using regex."""
|
|
188
|
+
if not uri:
|
|
189
|
+
return None
|
|
190
|
+
match = SCHEME_REGEX.match(uri)
|
|
191
|
+
return match.group(1).lower() if match else None
|
|
222
192
|
|
|
223
|
-
# Utility methods
|
|
224
193
|
def is_alias_registered(self, alias: str) -> bool:
|
|
225
194
|
"""Check if a named alias is registered."""
|
|
226
195
|
return alias in self._alias_configs
|
|
@@ -230,11 +199,7 @@ class StorageRegistry:
|
|
|
230
199
|
return list(self._alias_configs.keys())
|
|
231
200
|
|
|
232
201
|
def clear_cache(self, uri_or_alias: Optional[str] = None) -> None:
|
|
233
|
-
"""Clear resolved backend cache.
|
|
234
|
-
|
|
235
|
-
Args:
|
|
236
|
-
uri_or_alias: Specific URI or alias to clear, or None to clear all
|
|
237
|
-
"""
|
|
202
|
+
"""Clear resolved backend cache."""
|
|
238
203
|
if uri_or_alias:
|
|
239
204
|
self._instances.pop(uri_or_alias, None)
|
|
240
205
|
else:
|
|
@@ -256,17 +221,9 @@ class StorageRegistry:
|
|
|
256
221
|
self._aliases.clear()
|
|
257
222
|
|
|
258
223
|
def get_backend_capabilities(self, uri_or_alias: Union[str, Path]) -> "StorageCapabilities":
|
|
259
|
-
"""Get capabilities for a backend without creating an instance.
|
|
260
|
-
|
|
261
|
-
Args:
|
|
262
|
-
uri_or_alias: URI or alias to check capabilities for
|
|
263
|
-
|
|
264
|
-
Returns:
|
|
265
|
-
StorageCapabilities object describing backend capabilities
|
|
266
|
-
"""
|
|
224
|
+
"""Get capabilities for a backend without creating an instance."""
|
|
267
225
|
if isinstance(uri_or_alias, Path):
|
|
268
226
|
uri_or_alias = f"file://{uri_or_alias.resolve()}"
|
|
269
|
-
|
|
270
227
|
if "://" in uri_or_alias:
|
|
271
228
|
backend_cls = self._determine_backend_class(uri_or_alias)
|
|
272
229
|
elif uri_or_alias in self._alias_configs:
|
|
@@ -274,15 +231,9 @@ class StorageRegistry:
|
|
|
274
231
|
else:
|
|
275
232
|
msg = f"Unknown storage alias or invalid URI: '{uri_or_alias}'"
|
|
276
233
|
raise ImproperConfigurationError(msg)
|
|
277
|
-
|
|
278
|
-
# Get capabilities from the backend class
|
|
279
234
|
if hasattr(backend_cls, "capabilities"):
|
|
280
235
|
return backend_cls.capabilities
|
|
281
|
-
|
|
282
|
-
# Default capabilities if not defined
|
|
283
|
-
|
|
284
236
|
return StorageCapabilities()
|
|
285
237
|
|
|
286
238
|
|
|
287
|
-
# Global registry instance
|
|
288
239
|
storage_registry = StorageRegistry()
|
sqlspec/typing.py
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
# pyright: ignore[reportAttributeAccessIssue]
|
|
2
|
-
from collections.abc import Mapping
|
|
2
|
+
from collections.abc import Iterator, Mapping
|
|
3
3
|
from functools import lru_cache
|
|
4
|
-
from typing import TYPE_CHECKING, Annotated, Any, Union
|
|
4
|
+
from typing import TYPE_CHECKING, Annotated, Any, Protocol, Union
|
|
5
5
|
|
|
6
6
|
from typing_extensions import TypeAlias, TypeVar
|
|
7
7
|
|
|
8
8
|
from sqlspec._typing import (
|
|
9
9
|
AIOSQL_INSTALLED,
|
|
10
|
+
ATTRS_INSTALLED,
|
|
11
|
+
CATTRS_INSTALLED,
|
|
10
12
|
FSSPEC_INSTALLED,
|
|
11
13
|
LITESTAR_INSTALLED,
|
|
12
14
|
MSGSPEC_INSTALLED,
|
|
@@ -16,74 +18,141 @@ from sqlspec._typing import (
|
|
|
16
18
|
PROMETHEUS_INSTALLED,
|
|
17
19
|
PYARROW_INSTALLED,
|
|
18
20
|
PYDANTIC_INSTALLED,
|
|
19
|
-
UNSET,
|
|
20
|
-
AiosqlAsyncProtocol, # pyright: ignore[reportAttributeAccessIssue]
|
|
21
|
-
AiosqlParamType, # pyright: ignore[reportAttributeAccessIssue]
|
|
22
|
-
AiosqlProtocol, # pyright: ignore[reportAttributeAccessIssue]
|
|
23
|
-
AiosqlSQLOperationType, # pyright: ignore[reportAttributeAccessIssue]
|
|
24
|
-
AiosqlSyncProtocol, # pyright: ignore[reportAttributeAccessIssue]
|
|
25
|
-
ArrowRecordBatch,
|
|
26
|
-
ArrowTable,
|
|
27
|
-
BaseModel,
|
|
28
|
-
Counter, # pyright: ignore[reportAttributeAccessIssue]
|
|
29
21
|
DataclassProtocol,
|
|
30
|
-
DTOData,
|
|
31
22
|
Empty,
|
|
23
|
+
EmptyEnum,
|
|
32
24
|
EmptyType,
|
|
33
|
-
Gauge, # pyright: ignore[reportAttributeAccessIssue]
|
|
34
|
-
Histogram, # pyright: ignore[reportAttributeAccessIssue]
|
|
35
|
-
Span, # pyright: ignore[reportAttributeAccessIssue]
|
|
36
|
-
Status, # pyright: ignore[reportAttributeAccessIssue]
|
|
37
|
-
StatusCode, # pyright: ignore[reportAttributeAccessIssue]
|
|
38
|
-
Struct,
|
|
39
|
-
Tracer, # pyright: ignore[reportAttributeAccessIssue]
|
|
40
|
-
TypeAdapter,
|
|
41
|
-
UnsetType,
|
|
42
|
-
aiosql,
|
|
43
|
-
convert, # pyright: ignore[reportAttributeAccessIssue]
|
|
44
|
-
trace,
|
|
45
25
|
)
|
|
46
26
|
|
|
47
27
|
if TYPE_CHECKING:
|
|
48
28
|
from collections.abc import Sequence
|
|
49
29
|
|
|
30
|
+
from sqlspec._typing import (
|
|
31
|
+
UNSET,
|
|
32
|
+
AiosqlAsyncProtocol,
|
|
33
|
+
AiosqlParamType,
|
|
34
|
+
AiosqlProtocol,
|
|
35
|
+
AiosqlSQLOperationType,
|
|
36
|
+
AiosqlSyncProtocol,
|
|
37
|
+
ArrowRecordBatch,
|
|
38
|
+
ArrowTable,
|
|
39
|
+
AttrsInstance,
|
|
40
|
+
AttrsInstanceStub,
|
|
41
|
+
BaseModel,
|
|
42
|
+
BaseModelStub,
|
|
43
|
+
Counter,
|
|
44
|
+
DTOData,
|
|
45
|
+
FailFast,
|
|
46
|
+
Gauge,
|
|
47
|
+
Histogram,
|
|
48
|
+
Span,
|
|
49
|
+
Status,
|
|
50
|
+
StatusCode,
|
|
51
|
+
Struct,
|
|
52
|
+
StructStub,
|
|
53
|
+
Tracer,
|
|
54
|
+
TypeAdapter,
|
|
55
|
+
UnsetType,
|
|
56
|
+
aiosql,
|
|
57
|
+
attrs_asdict,
|
|
58
|
+
attrs_define,
|
|
59
|
+
attrs_field,
|
|
60
|
+
attrs_fields,
|
|
61
|
+
attrs_has,
|
|
62
|
+
cattrs_structure,
|
|
63
|
+
cattrs_unstructure,
|
|
64
|
+
convert,
|
|
65
|
+
trace,
|
|
66
|
+
)
|
|
67
|
+
else:
|
|
68
|
+
from sqlspec._typing import (
|
|
69
|
+
UNSET,
|
|
70
|
+
AiosqlAsyncProtocol,
|
|
71
|
+
AiosqlParamType,
|
|
72
|
+
AiosqlProtocol,
|
|
73
|
+
AiosqlSQLOperationType,
|
|
74
|
+
AiosqlSyncProtocol,
|
|
75
|
+
ArrowRecordBatch,
|
|
76
|
+
ArrowTable,
|
|
77
|
+
AttrsInstance,
|
|
78
|
+
BaseModel,
|
|
79
|
+
Counter,
|
|
80
|
+
DTOData,
|
|
81
|
+
FailFast,
|
|
82
|
+
Gauge,
|
|
83
|
+
Histogram,
|
|
84
|
+
Span,
|
|
85
|
+
Status,
|
|
86
|
+
StatusCode,
|
|
87
|
+
Struct,
|
|
88
|
+
Tracer,
|
|
89
|
+
TypeAdapter,
|
|
90
|
+
UnsetType,
|
|
91
|
+
aiosql,
|
|
92
|
+
attrs_asdict,
|
|
93
|
+
attrs_define,
|
|
94
|
+
attrs_field,
|
|
95
|
+
attrs_fields,
|
|
96
|
+
attrs_has,
|
|
97
|
+
cattrs_structure,
|
|
98
|
+
cattrs_unstructure,
|
|
99
|
+
convert,
|
|
100
|
+
trace,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class DictLike(Protocol):
|
|
105
|
+
"""A protocol for objects that behave like a dictionary for reading."""
|
|
106
|
+
|
|
107
|
+
def __getitem__(self, key: str) -> Any: ...
|
|
108
|
+
def __iter__(self) -> Iterator[str]: ...
|
|
109
|
+
def __len__(self) -> int: ...
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
PYDANTIC_USE_FAILFAST = False
|
|
50
113
|
|
|
51
|
-
PYDANTIC_USE_FAILFAST = False # leave permanently disabled for now
|
|
52
114
|
|
|
115
|
+
if TYPE_CHECKING:
|
|
116
|
+
T = TypeVar("T")
|
|
117
|
+
ConnectionT = TypeVar("ConnectionT")
|
|
118
|
+
"""Type variable for connection types.
|
|
53
119
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
""
|
|
57
|
-
|
|
58
|
-
:class:`~sqlspec.typing.ConnectionT`
|
|
59
|
-
"""
|
|
60
|
-
PoolT = TypeVar("PoolT")
|
|
61
|
-
"""Type variable for pool types.
|
|
120
|
+
:class:`~sqlspec.typing.ConnectionT`
|
|
121
|
+
"""
|
|
122
|
+
PoolT = TypeVar("PoolT")
|
|
123
|
+
"""Type variable for pool types.
|
|
62
124
|
|
|
63
|
-
:class:`~sqlspec.typing.PoolT`
|
|
64
|
-
"""
|
|
65
|
-
PoolT_co = TypeVar("PoolT_co", covariant=True)
|
|
66
|
-
"""Type variable for covariant pool types.
|
|
125
|
+
:class:`~sqlspec.typing.PoolT`
|
|
126
|
+
"""
|
|
127
|
+
PoolT_co = TypeVar("PoolT_co", covariant=True)
|
|
128
|
+
"""Type variable for covariant pool types.
|
|
67
129
|
|
|
68
|
-
:class:`~sqlspec.typing.PoolT_co`
|
|
69
|
-
"""
|
|
70
|
-
ModelT = TypeVar("ModelT", bound="Union[
|
|
71
|
-
"""Type variable for model types.
|
|
130
|
+
:class:`~sqlspec.typing.PoolT_co`
|
|
131
|
+
"""
|
|
132
|
+
ModelT = TypeVar("ModelT", bound="Union[DictLike, StructStub, BaseModelStub, DataclassProtocol, AttrsInstanceStub]")
|
|
133
|
+
"""Type variable for model types.
|
|
72
134
|
|
|
73
|
-
:class:`
|
|
74
|
-
"""
|
|
135
|
+
:class:`DictLike` | :class:`msgspec.Struct` | :class:`pydantic.BaseModel` | :class:`DataclassProtocol` | :class:`AttrsInstance`
|
|
136
|
+
"""
|
|
137
|
+
RowT = TypeVar("RowT", bound="dict[str, Any]")
|
|
138
|
+
else:
|
|
139
|
+
T = Any
|
|
140
|
+
ConnectionT = Any
|
|
141
|
+
PoolT = Any
|
|
142
|
+
PoolT_co = Any
|
|
143
|
+
ModelT = Any
|
|
144
|
+
RowT = dict[str, Any]
|
|
75
145
|
|
|
76
146
|
|
|
77
147
|
DictRow: TypeAlias = "dict[str, Any]"
|
|
78
148
|
"""Type variable for DictRow types."""
|
|
79
149
|
TupleRow: TypeAlias = "tuple[Any, ...]"
|
|
80
150
|
"""Type variable for TupleRow types."""
|
|
81
|
-
RowT = TypeVar("RowT", default=dict[str, Any])
|
|
82
151
|
|
|
83
|
-
SupportedSchemaModel: TypeAlias = "Union[
|
|
152
|
+
SupportedSchemaModel: TypeAlias = "Union[DictLike, StructStub, BaseModelStub, DataclassProtocol, AttrsInstanceStub]"
|
|
84
153
|
"""Type alias for pydantic or msgspec models.
|
|
85
154
|
|
|
86
|
-
:class:`msgspec.Struct` | :class:`pydantic.BaseModel` | :class:`DataclassProtocol`
|
|
155
|
+
:class:`msgspec.Struct` | :class:`pydantic.BaseModel` | :class:`DataclassProtocol` | :class:`AttrsInstance`
|
|
87
156
|
"""
|
|
88
157
|
StatementParameters: TypeAlias = "Union[Any, dict[str, Any], list[Any], tuple[Any, ...], None]"
|
|
89
158
|
"""Type alias for statement parameters.
|
|
@@ -94,8 +163,6 @@ Represents:
|
|
|
94
163
|
- :type:`tuple[Any, ...]`
|
|
95
164
|
- :type:`None`
|
|
96
165
|
"""
|
|
97
|
-
# Backward compatibility alias
|
|
98
|
-
SQLParameterType: TypeAlias = StatementParameters
|
|
99
166
|
ModelDTOT = TypeVar("ModelDTOT", bound="SupportedSchemaModel")
|
|
100
167
|
"""Type variable for model DTOs.
|
|
101
168
|
|
|
@@ -106,22 +173,24 @@ PydanticOrMsgspecT = SupportedSchemaModel
|
|
|
106
173
|
|
|
107
174
|
:class:`msgspec.Struct` or :class:`pydantic.BaseModel`
|
|
108
175
|
"""
|
|
109
|
-
ModelDict: TypeAlias =
|
|
176
|
+
ModelDict: TypeAlias = (
|
|
177
|
+
"Union[dict[str, Any], Union[DictLike, StructStub, BaseModelStub, DataclassProtocol, AttrsInstanceStub], Any]"
|
|
178
|
+
)
|
|
110
179
|
"""Type alias for model dictionaries.
|
|
111
180
|
|
|
112
181
|
Represents:
|
|
113
182
|
- :type:`dict[str, Any]` | :class:`DataclassProtocol` | :class:`msgspec.Struct` | :class:`pydantic.BaseModel`
|
|
114
183
|
"""
|
|
115
|
-
ModelDictList: TypeAlias =
|
|
184
|
+
ModelDictList: TypeAlias = (
|
|
185
|
+
"Sequence[Union[dict[str, Any], Union[DictLike, StructStub, BaseModelStub, DataclassProtocol, AttrsInstanceStub]]]"
|
|
186
|
+
)
|
|
116
187
|
"""Type alias for model dictionary lists.
|
|
117
188
|
|
|
118
189
|
A list or sequence of any of the following:
|
|
119
190
|
- :type:`Sequence`[:type:`dict[str, Any]` | :class:`DataclassProtocol` | :class:`msgspec.Struct` | :class:`pydantic.BaseModel`]
|
|
120
191
|
|
|
121
192
|
"""
|
|
122
|
-
BulkModelDict: TypeAlias =
|
|
123
|
-
"Union[Sequence[Union[dict[str, Any], SupportedSchemaModel]], DTOData[list[SupportedSchemaModel]]]"
|
|
124
|
-
)
|
|
193
|
+
BulkModelDict: TypeAlias = "Union[Sequence[Union[dict[str, Any], Union[DictLike, StructStub, BaseModelStub, DataclassProtocol, AttrsInstanceStub]]], Any]"
|
|
125
194
|
"""Type alias for bulk model dictionaries.
|
|
126
195
|
|
|
127
196
|
Represents:
|
|
@@ -131,7 +200,7 @@ Represents:
|
|
|
131
200
|
|
|
132
201
|
|
|
133
202
|
@lru_cache(typed=True)
|
|
134
|
-
def get_type_adapter(f: "type[T]") ->
|
|
203
|
+
def get_type_adapter(f: "type[T]") -> Any:
|
|
135
204
|
"""Caches and returns a pydantic type adapter.
|
|
136
205
|
|
|
137
206
|
Args:
|
|
@@ -159,6 +228,8 @@ def MixinOf(base: type[T]) -> type[T]: # noqa: N802
|
|
|
159
228
|
|
|
160
229
|
__all__ = (
|
|
161
230
|
"AIOSQL_INSTALLED",
|
|
231
|
+
"ATTRS_INSTALLED",
|
|
232
|
+
"CATTRS_INSTALLED",
|
|
162
233
|
"FSSPEC_INSTALLED",
|
|
163
234
|
"LITESTAR_INSTALLED",
|
|
164
235
|
"MSGSPEC_INSTALLED",
|
|
@@ -177,14 +248,17 @@ __all__ = (
|
|
|
177
248
|
"AiosqlSyncProtocol",
|
|
178
249
|
"ArrowRecordBatch",
|
|
179
250
|
"ArrowTable",
|
|
251
|
+
"AttrsInstance",
|
|
180
252
|
"BaseModel",
|
|
181
253
|
"BulkModelDict",
|
|
182
254
|
"ConnectionT",
|
|
183
255
|
"Counter",
|
|
184
256
|
"DTOData",
|
|
185
257
|
"DataclassProtocol",
|
|
258
|
+
"DictLike",
|
|
186
259
|
"DictRow",
|
|
187
260
|
"Empty",
|
|
261
|
+
"EmptyEnum",
|
|
188
262
|
"EmptyType",
|
|
189
263
|
"FailFast",
|
|
190
264
|
"Gauge",
|
|
@@ -201,7 +275,6 @@ __all__ = (
|
|
|
201
275
|
"PoolT_co",
|
|
202
276
|
"PydanticOrMsgspecT",
|
|
203
277
|
"RowT",
|
|
204
|
-
"SQLParameterType",
|
|
205
278
|
"Span",
|
|
206
279
|
"StatementParameters",
|
|
207
280
|
"Status",
|
|
@@ -213,66 +286,14 @@ __all__ = (
|
|
|
213
286
|
"TypeAdapter",
|
|
214
287
|
"UnsetType",
|
|
215
288
|
"aiosql",
|
|
289
|
+
"attrs_asdict",
|
|
290
|
+
"attrs_define",
|
|
291
|
+
"attrs_field",
|
|
292
|
+
"attrs_fields",
|
|
293
|
+
"attrs_has",
|
|
294
|
+
"cattrs_structure",
|
|
295
|
+
"cattrs_unstructure",
|
|
216
296
|
"convert",
|
|
217
297
|
"get_type_adapter",
|
|
218
298
|
"trace",
|
|
219
299
|
)
|
|
220
|
-
|
|
221
|
-
if TYPE_CHECKING:
|
|
222
|
-
if not PYDANTIC_INSTALLED:
|
|
223
|
-
from sqlspec._typing import BaseModel, FailFast, TypeAdapter
|
|
224
|
-
else:
|
|
225
|
-
from pydantic import BaseModel, FailFast, TypeAdapter # noqa: TC004
|
|
226
|
-
|
|
227
|
-
if not MSGSPEC_INSTALLED:
|
|
228
|
-
from sqlspec._typing import UNSET, Struct, UnsetType, convert
|
|
229
|
-
else:
|
|
230
|
-
from msgspec import UNSET, Struct, UnsetType, convert # noqa: TC004
|
|
231
|
-
|
|
232
|
-
if not PYARROW_INSTALLED:
|
|
233
|
-
from sqlspec._typing import ArrowRecordBatch, ArrowTable
|
|
234
|
-
else:
|
|
235
|
-
from pyarrow import RecordBatch as ArrowRecordBatch # noqa: TC004
|
|
236
|
-
from pyarrow import Table as ArrowTable # noqa: TC004
|
|
237
|
-
if not LITESTAR_INSTALLED:
|
|
238
|
-
from sqlspec._typing import DTOData
|
|
239
|
-
else:
|
|
240
|
-
from litestar.dto import DTOData # noqa: TC004
|
|
241
|
-
if not OPENTELEMETRY_INSTALLED:
|
|
242
|
-
from sqlspec._typing import Span, Status, StatusCode, Tracer, trace # noqa: TC004 # pyright: ignore
|
|
243
|
-
else:
|
|
244
|
-
from opentelemetry.trace import ( # pyright: ignore[reportMissingImports] # noqa: TC004
|
|
245
|
-
Span,
|
|
246
|
-
Status,
|
|
247
|
-
StatusCode,
|
|
248
|
-
Tracer,
|
|
249
|
-
)
|
|
250
|
-
if not PROMETHEUS_INSTALLED:
|
|
251
|
-
from sqlspec._typing import Counter, Gauge, Histogram # pyright: ignore
|
|
252
|
-
else:
|
|
253
|
-
from prometheus_client import Counter, Gauge, Histogram # noqa: TC004 # pyright: ignore # noqa: TC004
|
|
254
|
-
|
|
255
|
-
if not AIOSQL_INSTALLED:
|
|
256
|
-
from sqlspec._typing import (
|
|
257
|
-
AiosqlAsyncProtocol, # pyright: ignore[reportAttributeAccessIssue]
|
|
258
|
-
AiosqlParamType, # pyright: ignore[reportAttributeAccessIssue]
|
|
259
|
-
AiosqlProtocol, # pyright: ignore[reportAttributeAccessIssue]
|
|
260
|
-
AiosqlSQLOperationType, # pyright: ignore[reportAttributeAccessIssue]
|
|
261
|
-
AiosqlSyncProtocol, # pyright: ignore[reportAttributeAccessIssue]
|
|
262
|
-
aiosql,
|
|
263
|
-
)
|
|
264
|
-
else:
|
|
265
|
-
import aiosql # noqa: TC004 # pyright: ignore
|
|
266
|
-
from aiosql.types import ( # noqa: TC004 # pyright: ignore[reportMissingImports]
|
|
267
|
-
AsyncDriverAdapterProtocol as AiosqlAsyncProtocol,
|
|
268
|
-
)
|
|
269
|
-
from aiosql.types import ( # noqa: TC004 # pyright: ignore[reportMissingImports]
|
|
270
|
-
DriverAdapterProtocol as AiosqlProtocol,
|
|
271
|
-
)
|
|
272
|
-
from aiosql.types import ParamType as AiosqlParamType # noqa: TC004 # pyright: ignore[reportMissingImports]
|
|
273
|
-
from aiosql.types import (
|
|
274
|
-
SQLOperationType as AiosqlSQLOperationType, # noqa: TC004 # pyright: ignore[reportMissingImports]
|
|
275
|
-
)
|
|
276
|
-
from aiosql.types import ( # noqa: TC004 # pyright: ignore[reportMissingImports]
|
|
277
|
-
SyncDriverAdapterProtocol as AiosqlSyncProtocol,
|
|
278
|
-
)
|
sqlspec/utils/__init__.py
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
from sqlspec.utils import deprecation, fixtures, module_loader, singleton, sync_tools, text
|
|
1
|
+
from sqlspec.utils import deprecation, fixtures, module_loader, singleton, sync_tools, text, type_guards
|
|
2
2
|
|
|
3
|
-
__all__ = ("deprecation", "fixtures", "module_loader", "singleton", "sync_tools", "text")
|
|
3
|
+
__all__ = ("deprecation", "fixtures", "module_loader", "singleton", "sync_tools", "text", "type_guards")
|
sqlspec/utils/correlation.py
CHANGED
|
@@ -68,14 +68,12 @@ class CorrelationContext:
|
|
|
68
68
|
if correlation_id is None:
|
|
69
69
|
correlation_id = cls.generate()
|
|
70
70
|
|
|
71
|
-
# Save the current correlation ID
|
|
72
71
|
previous_id = cls.get()
|
|
73
72
|
|
|
74
73
|
try:
|
|
75
74
|
cls.set(correlation_id)
|
|
76
75
|
yield correlation_id
|
|
77
76
|
finally:
|
|
78
|
-
# Restore the previous correlation ID
|
|
79
77
|
cls.set(previous_id)
|
|
80
78
|
|
|
81
79
|
@classmethod
|
|
@@ -111,7 +109,6 @@ def correlation_context(correlation_id: str | None = None) -> Generator[str, Non
|
|
|
111
109
|
"Processing request",
|
|
112
110
|
extra={"correlation_id": correlation_id},
|
|
113
111
|
)
|
|
114
|
-
# All operations within this context will have the same correlation ID
|
|
115
112
|
```
|
|
116
113
|
"""
|
|
117
114
|
with CorrelationContext.context(correlation_id) as cid:
|