sqlspec 0.11.1__py3-none-any.whl → 0.12.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of sqlspec might be problematic. Click here for more details.
- sqlspec/__init__.py +16 -3
- sqlspec/_serialization.py +3 -10
- sqlspec/_sql.py +1147 -0
- sqlspec/_typing.py +343 -41
- sqlspec/adapters/adbc/__init__.py +2 -6
- sqlspec/adapters/adbc/config.py +474 -149
- sqlspec/adapters/adbc/driver.py +330 -621
- sqlspec/adapters/aiosqlite/__init__.py +2 -6
- sqlspec/adapters/aiosqlite/config.py +143 -57
- sqlspec/adapters/aiosqlite/driver.py +269 -431
- sqlspec/adapters/asyncmy/__init__.py +3 -8
- sqlspec/adapters/asyncmy/config.py +247 -202
- sqlspec/adapters/asyncmy/driver.py +218 -436
- sqlspec/adapters/asyncpg/__init__.py +4 -7
- sqlspec/adapters/asyncpg/config.py +329 -176
- sqlspec/adapters/asyncpg/driver.py +417 -487
- sqlspec/adapters/bigquery/__init__.py +2 -2
- sqlspec/adapters/bigquery/config.py +407 -0
- sqlspec/adapters/bigquery/driver.py +600 -553
- sqlspec/adapters/duckdb/__init__.py +4 -1
- sqlspec/adapters/duckdb/config.py +432 -321
- sqlspec/adapters/duckdb/driver.py +392 -406
- sqlspec/adapters/oracledb/__init__.py +3 -8
- sqlspec/adapters/oracledb/config.py +625 -0
- sqlspec/adapters/oracledb/driver.py +548 -921
- sqlspec/adapters/psqlpy/__init__.py +4 -7
- sqlspec/adapters/psqlpy/config.py +372 -203
- sqlspec/adapters/psqlpy/driver.py +197 -533
- sqlspec/adapters/psycopg/__init__.py +3 -8
- sqlspec/adapters/psycopg/config.py +741 -0
- sqlspec/adapters/psycopg/driver.py +734 -694
- sqlspec/adapters/sqlite/__init__.py +2 -6
- sqlspec/adapters/sqlite/config.py +146 -81
- sqlspec/adapters/sqlite/driver.py +242 -405
- sqlspec/base.py +220 -784
- sqlspec/config.py +354 -0
- sqlspec/driver/__init__.py +22 -0
- sqlspec/driver/_async.py +252 -0
- sqlspec/driver/_common.py +338 -0
- sqlspec/driver/_sync.py +261 -0
- sqlspec/driver/mixins/__init__.py +17 -0
- sqlspec/driver/mixins/_pipeline.py +523 -0
- sqlspec/driver/mixins/_result_utils.py +122 -0
- sqlspec/driver/mixins/_sql_translator.py +35 -0
- sqlspec/driver/mixins/_storage.py +993 -0
- sqlspec/driver/mixins/_type_coercion.py +131 -0
- sqlspec/exceptions.py +299 -7
- sqlspec/extensions/aiosql/__init__.py +10 -0
- sqlspec/extensions/aiosql/adapter.py +474 -0
- sqlspec/extensions/litestar/__init__.py +1 -6
- sqlspec/extensions/litestar/_utils.py +1 -5
- sqlspec/extensions/litestar/config.py +5 -6
- sqlspec/extensions/litestar/handlers.py +13 -12
- sqlspec/extensions/litestar/plugin.py +22 -24
- sqlspec/extensions/litestar/providers.py +37 -55
- sqlspec/loader.py +528 -0
- sqlspec/service/__init__.py +3 -0
- sqlspec/service/base.py +24 -0
- sqlspec/service/pagination.py +26 -0
- sqlspec/statement/__init__.py +21 -0
- sqlspec/statement/builder/__init__.py +54 -0
- sqlspec/statement/builder/_ddl_utils.py +119 -0
- sqlspec/statement/builder/_parsing_utils.py +135 -0
- sqlspec/statement/builder/base.py +328 -0
- sqlspec/statement/builder/ddl.py +1379 -0
- sqlspec/statement/builder/delete.py +80 -0
- sqlspec/statement/builder/insert.py +274 -0
- sqlspec/statement/builder/merge.py +95 -0
- sqlspec/statement/builder/mixins/__init__.py +65 -0
- sqlspec/statement/builder/mixins/_aggregate_functions.py +151 -0
- sqlspec/statement/builder/mixins/_case_builder.py +91 -0
- sqlspec/statement/builder/mixins/_common_table_expr.py +91 -0
- sqlspec/statement/builder/mixins/_delete_from.py +34 -0
- sqlspec/statement/builder/mixins/_from.py +61 -0
- sqlspec/statement/builder/mixins/_group_by.py +119 -0
- sqlspec/statement/builder/mixins/_having.py +35 -0
- sqlspec/statement/builder/mixins/_insert_from_select.py +48 -0
- sqlspec/statement/builder/mixins/_insert_into.py +36 -0
- sqlspec/statement/builder/mixins/_insert_values.py +69 -0
- sqlspec/statement/builder/mixins/_join.py +110 -0
- sqlspec/statement/builder/mixins/_limit_offset.py +53 -0
- sqlspec/statement/builder/mixins/_merge_clauses.py +405 -0
- sqlspec/statement/builder/mixins/_order_by.py +46 -0
- sqlspec/statement/builder/mixins/_pivot.py +82 -0
- sqlspec/statement/builder/mixins/_returning.py +37 -0
- sqlspec/statement/builder/mixins/_select_columns.py +60 -0
- sqlspec/statement/builder/mixins/_set_ops.py +122 -0
- sqlspec/statement/builder/mixins/_unpivot.py +80 -0
- sqlspec/statement/builder/mixins/_update_from.py +54 -0
- sqlspec/statement/builder/mixins/_update_set.py +91 -0
- sqlspec/statement/builder/mixins/_update_table.py +29 -0
- sqlspec/statement/builder/mixins/_where.py +374 -0
- sqlspec/statement/builder/mixins/_window_functions.py +86 -0
- sqlspec/statement/builder/protocols.py +20 -0
- sqlspec/statement/builder/select.py +206 -0
- sqlspec/statement/builder/update.py +178 -0
- sqlspec/statement/filters.py +571 -0
- sqlspec/statement/parameters.py +736 -0
- sqlspec/statement/pipelines/__init__.py +67 -0
- sqlspec/statement/pipelines/analyzers/__init__.py +9 -0
- sqlspec/statement/pipelines/analyzers/_analyzer.py +649 -0
- sqlspec/statement/pipelines/base.py +315 -0
- sqlspec/statement/pipelines/context.py +119 -0
- sqlspec/statement/pipelines/result_types.py +41 -0
- sqlspec/statement/pipelines/transformers/__init__.py +8 -0
- sqlspec/statement/pipelines/transformers/_expression_simplifier.py +256 -0
- sqlspec/statement/pipelines/transformers/_literal_parameterizer.py +623 -0
- sqlspec/statement/pipelines/transformers/_remove_comments.py +66 -0
- sqlspec/statement/pipelines/transformers/_remove_hints.py +81 -0
- sqlspec/statement/pipelines/validators/__init__.py +23 -0
- sqlspec/statement/pipelines/validators/_dml_safety.py +275 -0
- sqlspec/statement/pipelines/validators/_parameter_style.py +297 -0
- sqlspec/statement/pipelines/validators/_performance.py +703 -0
- sqlspec/statement/pipelines/validators/_security.py +990 -0
- sqlspec/statement/pipelines/validators/base.py +67 -0
- sqlspec/statement/result.py +527 -0
- sqlspec/statement/splitter.py +701 -0
- sqlspec/statement/sql.py +1198 -0
- sqlspec/storage/__init__.py +15 -0
- sqlspec/storage/backends/__init__.py +0 -0
- sqlspec/storage/backends/base.py +166 -0
- sqlspec/storage/backends/fsspec.py +315 -0
- sqlspec/storage/backends/obstore.py +464 -0
- sqlspec/storage/protocol.py +170 -0
- sqlspec/storage/registry.py +315 -0
- sqlspec/typing.py +157 -36
- sqlspec/utils/correlation.py +155 -0
- sqlspec/utils/deprecation.py +3 -6
- sqlspec/utils/fixtures.py +6 -11
- sqlspec/utils/logging.py +135 -0
- sqlspec/utils/module_loader.py +45 -43
- sqlspec/utils/serializers.py +4 -0
- sqlspec/utils/singleton.py +6 -8
- sqlspec/utils/sync_tools.py +15 -27
- sqlspec/utils/text.py +58 -26
- {sqlspec-0.11.1.dist-info → sqlspec-0.12.0.dist-info}/METADATA +97 -26
- sqlspec-0.12.0.dist-info/RECORD +145 -0
- sqlspec/adapters/bigquery/config/__init__.py +0 -3
- sqlspec/adapters/bigquery/config/_common.py +0 -40
- sqlspec/adapters/bigquery/config/_sync.py +0 -87
- sqlspec/adapters/oracledb/config/__init__.py +0 -9
- sqlspec/adapters/oracledb/config/_asyncio.py +0 -186
- sqlspec/adapters/oracledb/config/_common.py +0 -131
- sqlspec/adapters/oracledb/config/_sync.py +0 -186
- sqlspec/adapters/psycopg/config/__init__.py +0 -19
- sqlspec/adapters/psycopg/config/_async.py +0 -169
- sqlspec/adapters/psycopg/config/_common.py +0 -56
- sqlspec/adapters/psycopg/config/_sync.py +0 -168
- sqlspec/filters.py +0 -331
- sqlspec/mixins.py +0 -305
- sqlspec/statement.py +0 -378
- sqlspec-0.11.1.dist-info/RECORD +0 -69
- {sqlspec-0.11.1.dist-info → sqlspec-0.12.0.dist-info}/WHEEL +0 -0
- {sqlspec-0.11.1.dist-info → sqlspec-0.12.0.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.11.1.dist-info → sqlspec-0.12.0.dist-info}/licenses/NOTICE +0 -0
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
from sqlspec.adapters.aiosqlite.config import AiosqliteConfig
|
|
1
|
+
from sqlspec.adapters.aiosqlite.config import CONNECTION_FIELDS, AiosqliteConfig
|
|
2
2
|
from sqlspec.adapters.aiosqlite.driver import AiosqliteConnection, AiosqliteDriver
|
|
3
3
|
|
|
4
|
-
__all__ = (
|
|
5
|
-
"AiosqliteConfig",
|
|
6
|
-
"AiosqliteConnection",
|
|
7
|
-
"AiosqliteDriver",
|
|
8
|
-
)
|
|
4
|
+
__all__ = ("CONNECTION_FIELDS", "AiosqliteConfig", "AiosqliteConnection", "AiosqliteDriver")
|
|
@@ -1,87 +1,158 @@
|
|
|
1
|
+
"""Aiosqlite database configuration with direct field-based configuration."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from collections.abc import AsyncGenerator
|
|
1
5
|
from contextlib import asynccontextmanager
|
|
2
|
-
from dataclasses import
|
|
3
|
-
from typing import TYPE_CHECKING, Any,
|
|
6
|
+
from dataclasses import replace
|
|
7
|
+
from typing import TYPE_CHECKING, Any, ClassVar, Optional
|
|
4
8
|
|
|
5
9
|
import aiosqlite
|
|
6
10
|
|
|
7
11
|
from sqlspec.adapters.aiosqlite.driver import AiosqliteConnection, AiosqliteDriver
|
|
8
|
-
from sqlspec.
|
|
12
|
+
from sqlspec.config import AsyncDatabaseConfig
|
|
9
13
|
from sqlspec.exceptions import ImproperConfigurationError
|
|
10
|
-
from sqlspec.
|
|
14
|
+
from sqlspec.statement.sql import SQLConfig
|
|
15
|
+
from sqlspec.typing import DictRow, Empty
|
|
11
16
|
|
|
12
17
|
if TYPE_CHECKING:
|
|
13
|
-
from collections.abc import AsyncGenerator
|
|
14
18
|
from typing import Literal
|
|
15
19
|
|
|
20
|
+
from sqlglot.dialects.dialect import DialectType
|
|
21
|
+
|
|
16
22
|
|
|
17
|
-
__all__ = ("AiosqliteConfig"
|
|
23
|
+
__all__ = ("CONNECTION_FIELDS", "AiosqliteConfig")
|
|
18
24
|
|
|
25
|
+
logger = logging.getLogger(__name__)
|
|
19
26
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
27
|
+
CONNECTION_FIELDS = frozenset(
|
|
28
|
+
{"database", "timeout", "detect_types", "isolation_level", "check_same_thread", "cached_statements", "uri"}
|
|
29
|
+
)
|
|
23
30
|
|
|
24
|
-
This class provides configuration options for Aiosqlite database connections, wrapping all parameters
|
|
25
|
-
available to aiosqlite.connect().
|
|
26
31
|
|
|
27
|
-
|
|
32
|
+
class AiosqliteConfig(AsyncDatabaseConfig[AiosqliteConnection, None, AiosqliteDriver]):
|
|
33
|
+
"""Configuration for Aiosqlite database connections with direct field-based configuration.
|
|
34
|
+
|
|
35
|
+
Note: Aiosqlite doesn't support connection pooling, so pool_instance is always None.
|
|
28
36
|
"""
|
|
29
37
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
38
|
+
__slots__ = (
|
|
39
|
+
"_dialect",
|
|
40
|
+
"cached_statements",
|
|
41
|
+
"check_same_thread",
|
|
42
|
+
"database",
|
|
43
|
+
"default_row_type",
|
|
44
|
+
"detect_types",
|
|
45
|
+
"extras",
|
|
46
|
+
"isolation_level",
|
|
47
|
+
"pool_instance",
|
|
48
|
+
"statement_config",
|
|
49
|
+
"timeout",
|
|
50
|
+
"uri",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
is_async: ClassVar[bool] = True
|
|
54
|
+
supports_connection_pooling: ClassVar[bool] = False
|
|
55
|
+
|
|
56
|
+
driver_type: type[AiosqliteDriver] = AiosqliteDriver
|
|
57
|
+
connection_type: type[AiosqliteConnection] = AiosqliteConnection
|
|
58
|
+
|
|
59
|
+
# Parameter style support information
|
|
60
|
+
supported_parameter_styles: ClassVar[tuple[str, ...]] = ("qmark", "named_colon")
|
|
61
|
+
"""AIOSQLite supports ? (qmark) and :name (named_colon) parameter styles."""
|
|
62
|
+
|
|
63
|
+
preferred_parameter_style: ClassVar[str] = "qmark"
|
|
64
|
+
"""AIOSQLite's native parameter style is ? (qmark)."""
|
|
65
|
+
|
|
66
|
+
def __init__(
|
|
67
|
+
self,
|
|
68
|
+
database: str = ":memory:",
|
|
69
|
+
statement_config: Optional[SQLConfig] = None,
|
|
70
|
+
default_row_type: type[DictRow] = DictRow,
|
|
71
|
+
# Connection parameters
|
|
72
|
+
timeout: Optional[float] = None,
|
|
73
|
+
detect_types: Optional[int] = None,
|
|
74
|
+
isolation_level: Optional["Optional[Literal['DEFERRED', 'IMMEDIATE', 'EXCLUSIVE']]"] = None,
|
|
75
|
+
check_same_thread: Optional[bool] = None,
|
|
76
|
+
cached_statements: Optional[int] = None,
|
|
77
|
+
uri: Optional[bool] = None,
|
|
78
|
+
**kwargs: Any,
|
|
79
|
+
) -> None:
|
|
80
|
+
"""Initialize Aiosqlite configuration.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
database: The path to the database file to be opened. Pass ":memory:" for in-memory database
|
|
84
|
+
statement_config: Default SQL statement configuration
|
|
85
|
+
default_row_type: Default row type for results
|
|
86
|
+
timeout: How many seconds the connection should wait before raising an OperationalError when a table is locked
|
|
87
|
+
detect_types: Control whether and how data types are detected. It can be 0 (default) or a combination of PARSE_DECLTYPES and PARSE_COLNAMES
|
|
88
|
+
isolation_level: The isolation_level of the connection. This can be None for autocommit mode or one of "DEFERRED", "IMMEDIATE" or "EXCLUSIVE"
|
|
89
|
+
check_same_thread: If True (default), ProgrammingError is raised if the database connection is used by a thread other than the one that created it
|
|
90
|
+
cached_statements: The number of statements that SQLite will cache for this connection. The default is 128
|
|
91
|
+
uri: If set to True, database is interpreted as a URI with supported options
|
|
92
|
+
**kwargs: Additional parameters (stored in extras)
|
|
93
|
+
"""
|
|
94
|
+
# Store connection parameters as instance attributes
|
|
95
|
+
self.database = database
|
|
96
|
+
self.timeout = timeout
|
|
97
|
+
self.detect_types = detect_types
|
|
98
|
+
self.isolation_level = isolation_level
|
|
99
|
+
self.check_same_thread = check_same_thread
|
|
100
|
+
self.cached_statements = cached_statements
|
|
101
|
+
self.uri = uri
|
|
102
|
+
self.extras = kwargs or {}
|
|
103
|
+
# Store other config
|
|
104
|
+
self.statement_config = statement_config or SQLConfig()
|
|
105
|
+
self.default_row_type = default_row_type
|
|
106
|
+
self._dialect: DialectType = None
|
|
107
|
+
|
|
108
|
+
super().__init__()
|
|
48
109
|
|
|
49
110
|
@property
|
|
50
|
-
def connection_config_dict(self) ->
|
|
51
|
-
"""Return the connection configuration as a dict.
|
|
111
|
+
def connection_config_dict(self) -> dict[str, Any]:
|
|
112
|
+
"""Return the connection configuration as a dict for aiosqlite.connect()."""
|
|
113
|
+
# Gather non-None connection parameters
|
|
114
|
+
config = {
|
|
115
|
+
field: getattr(self, field)
|
|
116
|
+
for field in CONNECTION_FIELDS
|
|
117
|
+
if getattr(self, field, None) is not None and getattr(self, field) is not Empty
|
|
118
|
+
}
|
|
52
119
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"""
|
|
56
|
-
return dataclass_to_dict(
|
|
57
|
-
self,
|
|
58
|
-
exclude_empty=True,
|
|
59
|
-
convert_nested=False,
|
|
60
|
-
exclude={"pool_instance", "connection_type", "driver_type"},
|
|
61
|
-
)
|
|
120
|
+
# Merge extras parameters
|
|
121
|
+
config.update(self.extras)
|
|
62
122
|
|
|
63
|
-
|
|
64
|
-
"""Create and return a new database connection.
|
|
123
|
+
return config
|
|
65
124
|
|
|
66
|
-
|
|
67
|
-
|
|
125
|
+
async def _create_pool(self) -> None:
|
|
126
|
+
"""Aiosqlite doesn't support pooling."""
|
|
127
|
+
return
|
|
128
|
+
|
|
129
|
+
async def _close_pool(self) -> None:
|
|
130
|
+
"""Aiosqlite doesn't support pooling."""
|
|
131
|
+
return
|
|
68
132
|
|
|
69
|
-
|
|
70
|
-
|
|
133
|
+
async def create_connection(self) -> AiosqliteConnection:
|
|
134
|
+
"""Create a single async connection.
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
An Aiosqlite connection instance.
|
|
71
138
|
"""
|
|
72
139
|
try:
|
|
73
|
-
|
|
140
|
+
config = self.connection_config_dict
|
|
141
|
+
return await aiosqlite.connect(**config)
|
|
74
142
|
except Exception as e:
|
|
75
143
|
msg = f"Could not configure the Aiosqlite connection. Error: {e!s}"
|
|
76
144
|
raise ImproperConfigurationError(msg) from e
|
|
77
145
|
|
|
78
146
|
@asynccontextmanager
|
|
79
|
-
async def provide_connection(self, *args:
|
|
80
|
-
"""
|
|
147
|
+
async def provide_connection(self, *args: Any, **kwargs: Any) -> AsyncGenerator[AiosqliteConnection, None]:
|
|
148
|
+
"""Provide an async connection context manager.
|
|
149
|
+
|
|
150
|
+
Args:
|
|
151
|
+
*args: Additional arguments.
|
|
152
|
+
**kwargs: Additional keyword arguments.
|
|
81
153
|
|
|
82
154
|
Yields:
|
|
83
155
|
An Aiosqlite connection instance.
|
|
84
|
-
|
|
85
156
|
"""
|
|
86
157
|
connection = await self.create_connection()
|
|
87
158
|
try:
|
|
@@ -90,13 +161,28 @@ class AiosqliteConfig(NoPoolAsyncConfig["AiosqliteConnection", "AiosqliteDriver"
|
|
|
90
161
|
await connection.close()
|
|
91
162
|
|
|
92
163
|
@asynccontextmanager
|
|
93
|
-
async def provide_session(self, *args: Any, **kwargs: Any) ->
|
|
94
|
-
"""
|
|
95
|
-
|
|
96
|
-
Yields:
|
|
97
|
-
A Aiosqlite driver instance.
|
|
164
|
+
async def provide_session(self, *args: Any, **kwargs: Any) -> AsyncGenerator[AiosqliteDriver, None]:
|
|
165
|
+
"""Provide an async driver session context manager.
|
|
98
166
|
|
|
167
|
+
Args:
|
|
168
|
+
*args: Additional arguments.
|
|
169
|
+
**kwargs: Additional keyword arguments.
|
|
99
170
|
|
|
171
|
+
Yields:
|
|
172
|
+
An AiosqliteDriver instance.
|
|
100
173
|
"""
|
|
101
174
|
async with self.provide_connection(*args, **kwargs) as connection:
|
|
102
|
-
|
|
175
|
+
# Create statement config with parameter style info if not already set
|
|
176
|
+
statement_config = self.statement_config
|
|
177
|
+
if statement_config.allowed_parameter_styles is None:
|
|
178
|
+
statement_config = replace(
|
|
179
|
+
statement_config,
|
|
180
|
+
allowed_parameter_styles=self.supported_parameter_styles,
|
|
181
|
+
target_parameter_style=self.preferred_parameter_style,
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
yield self.driver_type(connection=connection, config=statement_config)
|
|
185
|
+
|
|
186
|
+
async def provide_pool(self, *args: Any, **kwargs: Any) -> None:
|
|
187
|
+
"""Aiosqlite doesn't support pooling."""
|
|
188
|
+
return
|