sqlspec 0.6.0__py3-none-any.whl → 0.7.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 +0 -1
- sqlspec/__metadata__.py +0 -2
- sqlspec/_serialization.py +55 -8
- sqlspec/_typing.py +69 -20
- sqlspec/adapters/adbc/config.py +6 -11
- sqlspec/adapters/aiosqlite/__init__.py +1 -1
- sqlspec/adapters/aiosqlite/config.py +12 -14
- sqlspec/adapters/asyncmy/__init__.py +1 -1
- sqlspec/adapters/asyncmy/config.py +44 -44
- sqlspec/adapters/asyncpg/config.py +26 -27
- sqlspec/adapters/duckdb/config.py +73 -77
- sqlspec/adapters/oracledb/config/_asyncio.py +9 -11
- sqlspec/adapters/oracledb/config/_common.py +50 -52
- sqlspec/adapters/oracledb/config/_sync.py +8 -10
- sqlspec/adapters/psycopg/config/_async.py +7 -9
- sqlspec/adapters/psycopg/config/_common.py +15 -17
- sqlspec/adapters/psycopg/config/_sync.py +7 -9
- sqlspec/adapters/sqlite/config.py +11 -13
- sqlspec/base.py +14 -8
- sqlspec/exceptions.py +4 -6
- sqlspec/extensions/litestar/plugin.py +8 -7
- sqlspec/filters.py +11 -13
- sqlspec/typing.py +110 -127
- sqlspec/utils/deprecation.py +8 -10
- sqlspec/utils/fixtures.py +3 -5
- sqlspec/utils/module_loader.py +4 -6
- sqlspec/utils/text.py +2 -3
- {sqlspec-0.6.0.dist-info → sqlspec-0.7.0.dist-info}/METADATA +8 -1
- sqlspec-0.7.0.dist-info/RECORD +46 -0
- sqlspec-0.6.0.dist-info/RECORD +0 -46
- {sqlspec-0.6.0.dist-info → sqlspec-0.7.0.dist-info}/WHEEL +0 -0
- {sqlspec-0.6.0.dist-info → sqlspec-0.7.0.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.6.0.dist-info → sqlspec-0.7.0.dist-info}/licenses/NOTICE +0 -0
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
1
|
from contextlib import contextmanager
|
|
4
2
|
from dataclasses import dataclass
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
6
4
|
|
|
7
5
|
from oracledb import create_pool as oracledb_create_pool # pyright: ignore[reportUnknownVariableType]
|
|
8
6
|
from oracledb.connection import Connection
|
|
@@ -44,16 +42,16 @@ class OracleSyncDatabaseConfig(SyncDatabaseConfig[Connection, ConnectionPool]):
|
|
|
44
42
|
options.([2](https://python-oracledb.readthedocs.io/en/latest/user_guide/tuning.html))
|
|
45
43
|
"""
|
|
46
44
|
|
|
47
|
-
pool_config: OracleSyncPoolConfig
|
|
45
|
+
pool_config: "Optional[OracleSyncPoolConfig]" = None
|
|
48
46
|
"""Oracle Pool configuration"""
|
|
49
|
-
pool_instance: ConnectionPool
|
|
47
|
+
pool_instance: "Optional[ConnectionPool]" = None
|
|
50
48
|
"""Optional pool to use.
|
|
51
49
|
|
|
52
50
|
If set, the plugin will use the provided pool rather than instantiate one.
|
|
53
51
|
"""
|
|
54
52
|
|
|
55
53
|
@property
|
|
56
|
-
def pool_config_dict(self) -> dict[str, Any]:
|
|
54
|
+
def pool_config_dict(self) -> "dict[str, Any]":
|
|
57
55
|
"""Return the pool configuration as a dict.
|
|
58
56
|
|
|
59
57
|
Returns:
|
|
@@ -65,7 +63,7 @@ class OracleSyncDatabaseConfig(SyncDatabaseConfig[Connection, ConnectionPool]):
|
|
|
65
63
|
msg = "'pool_config' methods can not be used when a 'pool_instance' is provided."
|
|
66
64
|
raise ImproperConfigurationError(msg)
|
|
67
65
|
|
|
68
|
-
def create_pool(self) -> ConnectionPool:
|
|
66
|
+
def create_pool(self) -> "ConnectionPool":
|
|
69
67
|
"""Return a pool. If none exists yet, create one.
|
|
70
68
|
|
|
71
69
|
Returns:
|
|
@@ -81,11 +79,11 @@ class OracleSyncDatabaseConfig(SyncDatabaseConfig[Connection, ConnectionPool]):
|
|
|
81
79
|
pool_config = self.pool_config_dict
|
|
82
80
|
self.pool_instance = oracledb_create_pool(**pool_config)
|
|
83
81
|
if self.pool_instance is None: # pyright: ignore[reportUnnecessaryComparison]
|
|
84
|
-
msg = "Could not configure the 'pool_instance'. Please check your configuration."
|
|
82
|
+
msg = "Could not configure the 'pool_instance'. Please check your configuration." # type: ignore[unreachable]
|
|
85
83
|
raise ImproperConfigurationError(msg)
|
|
86
84
|
return self.pool_instance
|
|
87
85
|
|
|
88
|
-
def provide_pool(self, *args: Any, **kwargs: Any) -> ConnectionPool:
|
|
86
|
+
def provide_pool(self, *args: "Any", **kwargs: "Any") -> "ConnectionPool":
|
|
89
87
|
"""Create a pool instance.
|
|
90
88
|
|
|
91
89
|
Returns:
|
|
@@ -94,7 +92,7 @@ class OracleSyncDatabaseConfig(SyncDatabaseConfig[Connection, ConnectionPool]):
|
|
|
94
92
|
return self.create_pool()
|
|
95
93
|
|
|
96
94
|
@contextmanager
|
|
97
|
-
def provide_connection(self, *args: Any, **kwargs: Any) -> Generator[Connection, None, None]:
|
|
95
|
+
def provide_connection(self, *args: "Any", **kwargs: "Any") -> "Generator[Connection, None, None]":
|
|
98
96
|
"""Create a connection instance.
|
|
99
97
|
|
|
100
98
|
Returns:
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
1
|
from contextlib import asynccontextmanager
|
|
4
2
|
from dataclasses import dataclass
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
6
4
|
|
|
7
5
|
from psycopg import AsyncConnection
|
|
8
6
|
from psycopg_pool import AsyncConnectionPool
|
|
@@ -39,20 +37,20 @@ class PsycoPgAsyncDatabaseConfig(AsyncDatabaseConfig[AsyncConnection, AsyncConne
|
|
|
39
37
|
with both synchronous and asynchronous connections.([2](https://www.psycopg.org/psycopg3/docs/api/connections.html))
|
|
40
38
|
"""
|
|
41
39
|
|
|
42
|
-
pool_config: PsycoPgAsyncPoolConfig
|
|
40
|
+
pool_config: "Optional[PsycoPgAsyncPoolConfig]" = None
|
|
43
41
|
"""Psycopg Pool configuration"""
|
|
44
|
-
pool_instance: AsyncConnectionPool
|
|
42
|
+
pool_instance: "Optional[AsyncConnectionPool]" = None
|
|
45
43
|
"""Optional pool to use"""
|
|
46
44
|
|
|
47
45
|
@property
|
|
48
|
-
def pool_config_dict(self) -> dict[str, Any]:
|
|
46
|
+
def pool_config_dict(self) -> "dict[str, Any]":
|
|
49
47
|
"""Return the pool configuration as a dict."""
|
|
50
48
|
if self.pool_config:
|
|
51
49
|
return dataclass_to_dict(self.pool_config, exclude_empty=True, convert_nested=False)
|
|
52
50
|
msg = "'pool_config' methods can not be used when a 'pool_instance' is provided."
|
|
53
51
|
raise ImproperConfigurationError(msg)
|
|
54
52
|
|
|
55
|
-
async def create_pool(self) -> AsyncConnectionPool:
|
|
53
|
+
async def create_pool(self) -> "AsyncConnectionPool":
|
|
56
54
|
"""Create and return a connection pool."""
|
|
57
55
|
if self.pool_instance is not None:
|
|
58
56
|
return self.pool_instance
|
|
@@ -68,12 +66,12 @@ class PsycoPgAsyncDatabaseConfig(AsyncDatabaseConfig[AsyncConnection, AsyncConne
|
|
|
68
66
|
raise ImproperConfigurationError(msg)
|
|
69
67
|
return self.pool_instance
|
|
70
68
|
|
|
71
|
-
def provide_pool(self, *args: Any, **kwargs: Any) -> Awaitable[AsyncConnectionPool]:
|
|
69
|
+
def provide_pool(self, *args: "Any", **kwargs: "Any") -> "Awaitable[AsyncConnectionPool]":
|
|
72
70
|
"""Create and return a connection pool."""
|
|
73
71
|
return self.create_pool()
|
|
74
72
|
|
|
75
73
|
@asynccontextmanager
|
|
76
|
-
async def provide_connection(self, *args: Any, **kwargs: Any) -> AsyncGenerator[AsyncConnection, None]:
|
|
74
|
+
async def provide_connection(self, *args: "Any", **kwargs: "Any") -> "AsyncGenerator[AsyncConnection, None]":
|
|
77
75
|
"""Create and provide a database connection."""
|
|
78
76
|
pool = await self.provide_pool(*args, **kwargs)
|
|
79
77
|
async with pool.connection() as connection:
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
1
|
from dataclasses import dataclass
|
|
4
|
-
from typing import TYPE_CHECKING, Generic, TypeVar
|
|
2
|
+
from typing import TYPE_CHECKING, Generic, TypeVar, Union
|
|
5
3
|
|
|
6
4
|
from sqlspec.base import GenericPoolConfig
|
|
7
5
|
from sqlspec.typing import Empty
|
|
@@ -19,8 +17,8 @@ if TYPE_CHECKING:
|
|
|
19
17
|
__all__ = ("PsycoPgGenericPoolConfig",)
|
|
20
18
|
|
|
21
19
|
|
|
22
|
-
ConnectionT = TypeVar("ConnectionT", bound="Connection
|
|
23
|
-
PoolT = TypeVar("PoolT", bound="ConnectionPool
|
|
20
|
+
ConnectionT = TypeVar("ConnectionT", bound="Union[Connection, AsyncConnection]")
|
|
21
|
+
PoolT = TypeVar("PoolT", bound="Union[ConnectionPool, AsyncConnectionPool]")
|
|
24
22
|
|
|
25
23
|
|
|
26
24
|
@dataclass
|
|
@@ -32,27 +30,27 @@ class PsycoPgGenericPoolConfig(Generic[ConnectionT, PoolT], GenericPoolConfig):
|
|
|
32
30
|
settings.([1](https://www.psycopg.org/psycopg3/docs/api/pool.html))
|
|
33
31
|
"""
|
|
34
32
|
|
|
35
|
-
conninfo: str
|
|
33
|
+
conninfo: "Union[str, EmptyType]" = Empty
|
|
36
34
|
"""Connection string in libpq format"""
|
|
37
|
-
kwargs: dict[str, Any]
|
|
35
|
+
kwargs: "Union[dict[str, Any], EmptyType]" = Empty
|
|
38
36
|
"""Additional connection parameters"""
|
|
39
|
-
min_size: int
|
|
37
|
+
min_size: "Union[int, EmptyType]" = Empty
|
|
40
38
|
"""Minimum number of connections in the pool"""
|
|
41
|
-
max_size: int
|
|
39
|
+
max_size: "Union[int, EmptyType]" = Empty
|
|
42
40
|
"""Maximum number of connections in the pool"""
|
|
43
|
-
name: str
|
|
41
|
+
name: "Union[str, EmptyType]" = Empty
|
|
44
42
|
"""Name of the connection pool"""
|
|
45
|
-
timeout: float
|
|
43
|
+
timeout: "Union[float, EmptyType]" = Empty
|
|
46
44
|
"""Timeout for acquiring connections"""
|
|
47
|
-
max_waiting: int
|
|
45
|
+
max_waiting: "Union[int, EmptyType]" = Empty
|
|
48
46
|
"""Maximum number of waiting clients"""
|
|
49
|
-
max_lifetime: float
|
|
47
|
+
max_lifetime: "Union[float, EmptyType]" = Empty
|
|
50
48
|
"""Maximum connection lifetime"""
|
|
51
|
-
max_idle: float
|
|
49
|
+
max_idle: "Union[float, EmptyType]" = Empty
|
|
52
50
|
"""Maximum idle time for connections"""
|
|
53
|
-
reconnect_timeout: float
|
|
51
|
+
reconnect_timeout: "Union[float, EmptyType]" = Empty
|
|
54
52
|
"""Time between reconnection attempts"""
|
|
55
|
-
num_workers: int
|
|
53
|
+
num_workers: "Union[int, EmptyType]" = Empty
|
|
56
54
|
"""Number of background workers"""
|
|
57
|
-
configure: Callable[[ConnectionT], None]
|
|
55
|
+
configure: "Union[Callable[[ConnectionT], None], EmptyType]" = Empty
|
|
58
56
|
"""Callback to configure new connections"""
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
1
|
from contextlib import contextmanager
|
|
4
2
|
from dataclasses import dataclass
|
|
5
|
-
from typing import TYPE_CHECKING
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
6
4
|
|
|
7
5
|
from psycopg import Connection
|
|
8
6
|
from psycopg_pool import ConnectionPool
|
|
@@ -38,20 +36,20 @@ class PsycoPgSyncDatabaseConfig(SyncDatabaseConfig[Connection, ConnectionPool]):
|
|
|
38
36
|
with both synchronous and asynchronous connections.([2](https://www.psycopg.org/psycopg3/docs/api/connections.html))
|
|
39
37
|
"""
|
|
40
38
|
|
|
41
|
-
pool_config: PsycoPgSyncPoolConfig
|
|
39
|
+
pool_config: "Optional[PsycoPgSyncPoolConfig]" = None
|
|
42
40
|
"""Psycopg Pool configuration"""
|
|
43
|
-
pool_instance: ConnectionPool
|
|
41
|
+
pool_instance: "Optional[ConnectionPool]" = None
|
|
44
42
|
"""Optional pool to use"""
|
|
45
43
|
|
|
46
44
|
@property
|
|
47
|
-
def pool_config_dict(self) -> dict[str, Any]:
|
|
45
|
+
def pool_config_dict(self) -> "dict[str, Any]":
|
|
48
46
|
"""Return the pool configuration as a dict."""
|
|
49
47
|
if self.pool_config:
|
|
50
48
|
return dataclass_to_dict(self.pool_config, exclude_empty=True, convert_nested=False)
|
|
51
49
|
msg = "'pool_config' methods can not be used when a 'pool_instance' is provided."
|
|
52
50
|
raise ImproperConfigurationError(msg)
|
|
53
51
|
|
|
54
|
-
def create_pool(self) -> ConnectionPool:
|
|
52
|
+
def create_pool(self) -> "ConnectionPool":
|
|
55
53
|
"""Create and return a connection pool."""
|
|
56
54
|
if self.pool_instance is not None:
|
|
57
55
|
return self.pool_instance
|
|
@@ -67,12 +65,12 @@ class PsycoPgSyncDatabaseConfig(SyncDatabaseConfig[Connection, ConnectionPool]):
|
|
|
67
65
|
raise ImproperConfigurationError(msg)
|
|
68
66
|
return self.pool_instance
|
|
69
67
|
|
|
70
|
-
def provide_pool(self, *args: Any, **kwargs: Any) -> ConnectionPool:
|
|
68
|
+
def provide_pool(self, *args: "Any", **kwargs: "Any") -> "ConnectionPool":
|
|
71
69
|
"""Create and return a connection pool."""
|
|
72
70
|
return self.create_pool()
|
|
73
71
|
|
|
74
72
|
@contextmanager
|
|
75
|
-
def provide_connection(self, *args: Any, **kwargs: Any) -> Generator[Connection, None, None]:
|
|
73
|
+
def provide_connection(self, *args: "Any", **kwargs: "Any") -> "Generator[Connection, None, None]":
|
|
76
74
|
"""Create and provide a database connection."""
|
|
77
75
|
pool = self.provide_pool(*args, **kwargs)
|
|
78
76
|
with pool.connection() as connection:
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
1
|
from contextlib import contextmanager
|
|
4
2
|
from dataclasses import dataclass
|
|
5
|
-
from typing import TYPE_CHECKING, Any, Literal
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Literal, Optional, Union
|
|
6
4
|
|
|
7
5
|
from sqlspec.base import NoPoolSyncConfig
|
|
8
6
|
from sqlspec.exceptions import ImproperConfigurationError
|
|
@@ -28,29 +26,29 @@ class SqliteConfig(NoPoolSyncConfig["Connection"]):
|
|
|
28
26
|
database: str = ":memory:"
|
|
29
27
|
"""The path to the database file to be opened. Pass ":memory:" to open a connection to a database that resides in RAM instead of on disk."""
|
|
30
28
|
|
|
31
|
-
timeout: float
|
|
29
|
+
timeout: "Union[float, EmptyType]" = Empty
|
|
32
30
|
"""How many seconds the connection should wait before raising an OperationalError when a table is locked. If another thread or process has acquired a shared lock, a wait for the specified timeout occurs."""
|
|
33
31
|
|
|
34
|
-
detect_types: int
|
|
32
|
+
detect_types: "Union[int, EmptyType]" = Empty
|
|
35
33
|
"""Control whether and how data types are detected. It can be 0 (default) or a combination of PARSE_DECLTYPES and PARSE_COLNAMES."""
|
|
36
34
|
|
|
37
|
-
isolation_level: Literal[
|
|
35
|
+
isolation_level: "Optional[Union[Literal['DEFERRED', 'IMMEDIATE', 'EXCLUSIVE'], EmptyType]]" = Empty
|
|
38
36
|
"""The isolation_level of the connection. This can be None for autocommit mode or one of "DEFERRED", "IMMEDIATE" or "EXCLUSIVE"."""
|
|
39
37
|
|
|
40
|
-
check_same_thread: bool
|
|
38
|
+
check_same_thread: "Union[bool, EmptyType]" = Empty
|
|
41
39
|
"""If True (default), ProgrammingError is raised if the database connection is used by a thread other than the one that created it. If False, the connection may be shared across multiple threads."""
|
|
42
40
|
|
|
43
|
-
factory: type[Connection]
|
|
41
|
+
factory: "Union[type[Connection], EmptyType]" = Empty
|
|
44
42
|
"""A custom Connection class factory. If given, must be a callable that returns a Connection instance."""
|
|
45
43
|
|
|
46
|
-
cached_statements: int
|
|
44
|
+
cached_statements: "Union[int, EmptyType]" = Empty
|
|
47
45
|
"""The number of statements that SQLite will cache for this connection. The default is 128."""
|
|
48
46
|
|
|
49
|
-
uri: bool
|
|
47
|
+
uri: "Union[bool, EmptyType]" = Empty
|
|
50
48
|
"""If set to True, database is interpreted as a URI with supported options."""
|
|
51
49
|
|
|
52
50
|
@property
|
|
53
|
-
def connection_config_dict(self) -> dict[str, Any]:
|
|
51
|
+
def connection_config_dict(self) -> "dict[str, Any]":
|
|
54
52
|
"""Return the connection configuration as a dict.
|
|
55
53
|
|
|
56
54
|
Returns:
|
|
@@ -58,7 +56,7 @@ class SqliteConfig(NoPoolSyncConfig["Connection"]):
|
|
|
58
56
|
"""
|
|
59
57
|
return dataclass_to_dict(self, exclude_empty=True, convert_nested=False)
|
|
60
58
|
|
|
61
|
-
def create_connection(self) -> Connection:
|
|
59
|
+
def create_connection(self) -> "Connection":
|
|
62
60
|
"""Create and return a new database connection.
|
|
63
61
|
|
|
64
62
|
Returns:
|
|
@@ -76,7 +74,7 @@ class SqliteConfig(NoPoolSyncConfig["Connection"]):
|
|
|
76
74
|
raise ImproperConfigurationError(msg) from e
|
|
77
75
|
|
|
78
76
|
@contextmanager
|
|
79
|
-
def provide_connection(self, *args: Any, **kwargs: Any) -> Generator[Connection, None, None]:
|
|
77
|
+
def provide_connection(self, *args: "Any", **kwargs: "Any") -> "Generator[Connection, None, None]":
|
|
80
78
|
"""Create and provide a database connection.
|
|
81
79
|
|
|
82
80
|
Yields:
|
sqlspec/base.py
CHANGED
|
@@ -36,7 +36,9 @@ class DatabaseConfigProtocol(Generic[ConnectionT, PoolT], ABC):
|
|
|
36
36
|
|
|
37
37
|
@abstractmethod
|
|
38
38
|
def provide_connection(
|
|
39
|
-
self,
|
|
39
|
+
self,
|
|
40
|
+
*args: Any,
|
|
41
|
+
**kwargs: Any,
|
|
40
42
|
) -> Union[
|
|
41
43
|
Generator[ConnectionT, None, None],
|
|
42
44
|
AsyncGenerator[ConnectionT, None],
|
|
@@ -59,7 +61,9 @@ class DatabaseConfigProtocol(Generic[ConnectionT, PoolT], ABC):
|
|
|
59
61
|
|
|
60
62
|
@abstractmethod
|
|
61
63
|
def provide_pool(
|
|
62
|
-
self,
|
|
64
|
+
self,
|
|
65
|
+
*args: Any,
|
|
66
|
+
**kwargs: Any,
|
|
63
67
|
) -> Union[PoolT, Awaitable[PoolT], AbstractContextManager[PoolT], AbstractAsyncContextManager[PoolT]]:
|
|
64
68
|
"""Provide pool instance."""
|
|
65
69
|
raise NotImplementedError
|
|
@@ -157,12 +161,14 @@ class ConfigManager:
|
|
|
157
161
|
def get_config(self, name: type[AsyncConfigT]) -> AsyncConfigT: ...
|
|
158
162
|
|
|
159
163
|
def get_config(
|
|
160
|
-
self,
|
|
164
|
+
self,
|
|
165
|
+
name: Union[type[DatabaseConfigProtocol[ConnectionT, PoolT]], Any],
|
|
161
166
|
) -> DatabaseConfigProtocol[ConnectionT, PoolT]:
|
|
162
167
|
"""Retrieve a configuration by its type."""
|
|
163
168
|
config = self._configs.get(name)
|
|
164
169
|
if not config:
|
|
165
|
-
|
|
170
|
+
msg = f"No configuration found for {name}"
|
|
171
|
+
raise KeyError(msg)
|
|
166
172
|
return config
|
|
167
173
|
|
|
168
174
|
@overload
|
|
@@ -170,18 +176,18 @@ class ConfigManager:
|
|
|
170
176
|
self,
|
|
171
177
|
name: Union[
|
|
172
178
|
type[NoPoolSyncConfig[ConnectionT]],
|
|
173
|
-
type[SyncDatabaseConfig[ConnectionT, PoolT]],
|
|
179
|
+
type[SyncDatabaseConfig[ConnectionT, PoolT]], # pyright: ignore[reportInvalidTypeVarUse]
|
|
174
180
|
],
|
|
175
|
-
) -> ConnectionT: ...
|
|
181
|
+
) -> ConnectionT: ...
|
|
176
182
|
|
|
177
183
|
@overload
|
|
178
184
|
def get_connection(
|
|
179
185
|
self,
|
|
180
186
|
name: Union[
|
|
181
187
|
type[NoPoolAsyncConfig[ConnectionT]],
|
|
182
|
-
type[AsyncDatabaseConfig[ConnectionT, PoolT]],
|
|
188
|
+
type[AsyncDatabaseConfig[ConnectionT, PoolT]], # pyright: ignore[reportInvalidTypeVarUse]
|
|
183
189
|
],
|
|
184
|
-
) -> Awaitable[ConnectionT]: ...
|
|
190
|
+
) -> Awaitable[ConnectionT]: ...
|
|
185
191
|
|
|
186
192
|
def get_connection(
|
|
187
193
|
self,
|
sqlspec/exceptions.py
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
from
|
|
2
|
-
|
|
3
|
-
from typing import Any
|
|
1
|
+
from typing import Any, Optional
|
|
4
2
|
|
|
5
3
|
__all__ = (
|
|
6
4
|
"ImproperConfigurationError",
|
|
@@ -50,7 +48,7 @@ class MissingDependencyError(SQLSpecError, ImportError):
|
|
|
50
48
|
This exception is raised only when a module depends on a dependency that has not been installed.
|
|
51
49
|
"""
|
|
52
50
|
|
|
53
|
-
def __init__(self, package: str, install_package: str
|
|
51
|
+
def __init__(self, package: str, install_package: Optional[str] = None) -> None:
|
|
54
52
|
super().__init__(
|
|
55
53
|
f"Package {package!r} is not installed but required. You can install it by running "
|
|
56
54
|
f"'pip install sqlspec[{install_package or package}]' to install sqlspec with the required extra "
|
|
@@ -61,7 +59,7 @@ class MissingDependencyError(SQLSpecError, ImportError):
|
|
|
61
59
|
class SQLLoadingError(SQLSpecError):
|
|
62
60
|
"""Issues loading referenced SQL file."""
|
|
63
61
|
|
|
64
|
-
def __init__(self, message: str
|
|
62
|
+
def __init__(self, message: Optional[str] = None) -> None:
|
|
65
63
|
if message is None:
|
|
66
64
|
message = "Issues loading referenced SQL file."
|
|
67
65
|
super().__init__(message)
|
|
@@ -70,7 +68,7 @@ class SQLLoadingError(SQLSpecError):
|
|
|
70
68
|
class SQLParsingError(SQLSpecError):
|
|
71
69
|
"""Issues parsing SQL statements."""
|
|
72
70
|
|
|
73
|
-
def __init__(self, message: str
|
|
71
|
+
def __init__(self, message: Optional[str] = None) -> None:
|
|
74
72
|
if message is None:
|
|
75
73
|
message = "Issues parsing SQL statement."
|
|
76
74
|
super().__init__(message)
|
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
1
|
from typing import TYPE_CHECKING
|
|
4
2
|
|
|
5
3
|
from litestar.plugins import InitPluginProtocol
|
|
6
4
|
|
|
7
|
-
from sqlspec.base import ConfigManager
|
|
8
|
-
|
|
9
5
|
if TYPE_CHECKING:
|
|
10
6
|
from litestar.config.app import AppConfig
|
|
11
7
|
|
|
8
|
+
from sqlspec.base import ConfigManager
|
|
9
|
+
|
|
12
10
|
|
|
13
11
|
class SQLSpecPlugin(InitPluginProtocol):
|
|
14
12
|
"""SQLSpec plugin."""
|
|
15
13
|
|
|
16
14
|
__slots__ = ("_config",)
|
|
17
15
|
|
|
18
|
-
def __init__(self, config: ConfigManager) -> None:
|
|
16
|
+
def __init__(self, config: "ConfigManager") -> None:
|
|
19
17
|
"""Initialize ``SQLSpecPlugin``.
|
|
20
18
|
|
|
21
19
|
Args:
|
|
@@ -24,7 +22,7 @@ class SQLSpecPlugin(InitPluginProtocol):
|
|
|
24
22
|
self._config = config
|
|
25
23
|
|
|
26
24
|
@property
|
|
27
|
-
def config(self) -> ConfigManager:
|
|
25
|
+
def config(self) -> "ConfigManager":
|
|
28
26
|
"""Return the plugin config.
|
|
29
27
|
|
|
30
28
|
Returns:
|
|
@@ -32,11 +30,14 @@ class SQLSpecPlugin(InitPluginProtocol):
|
|
|
32
30
|
"""
|
|
33
31
|
return self._config
|
|
34
32
|
|
|
35
|
-
def on_app_init(self, app_config: AppConfig) -> AppConfig:
|
|
33
|
+
def on_app_init(self, app_config: "AppConfig") -> "AppConfig":
|
|
36
34
|
"""Configure application for use with SQLSpec.
|
|
37
35
|
|
|
38
36
|
Args:
|
|
39
37
|
app_config: The :class:`AppConfig <.config.app.AppConfig>` instance.
|
|
40
38
|
"""
|
|
39
|
+
|
|
40
|
+
from sqlspec.base import ConfigManager
|
|
41
|
+
|
|
41
42
|
app_config.signature_types.append(ConfigManager)
|
|
42
43
|
return app_config
|
sqlspec/filters.py
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
"""Collection filter datastructures."""
|
|
2
2
|
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
3
|
from abc import ABC
|
|
6
|
-
from collections import abc
|
|
4
|
+
from collections import abc
|
|
7
5
|
from dataclasses import dataclass
|
|
8
|
-
from datetime import datetime
|
|
9
|
-
from typing import Generic, Literal, Protocol
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from typing import Generic, Literal, Optional, Protocol, Union
|
|
10
8
|
|
|
11
9
|
from typing_extensions import TypeVar
|
|
12
10
|
|
|
@@ -42,9 +40,9 @@ class BeforeAfter(StatementFilter):
|
|
|
42
40
|
|
|
43
41
|
field_name: str
|
|
44
42
|
"""Name of the model attribute to filter on."""
|
|
45
|
-
before: datetime
|
|
43
|
+
before: Optional[datetime] = None
|
|
46
44
|
"""Filter results where field earlier than this."""
|
|
47
|
-
after: datetime
|
|
45
|
+
after: Optional[datetime] = None
|
|
48
46
|
"""Filter results where field later than this."""
|
|
49
47
|
|
|
50
48
|
|
|
@@ -54,9 +52,9 @@ class OnBeforeAfter(StatementFilter):
|
|
|
54
52
|
|
|
55
53
|
field_name: str
|
|
56
54
|
"""Name of the model attribute to filter on."""
|
|
57
|
-
on_or_before: datetime
|
|
55
|
+
on_or_before: Optional[datetime] = None
|
|
58
56
|
"""Filter results where field is on or earlier than this."""
|
|
59
|
-
on_or_after: datetime
|
|
57
|
+
on_or_after: Optional[datetime] = None
|
|
60
58
|
"""Filter results where field on or later than this."""
|
|
61
59
|
|
|
62
60
|
|
|
@@ -70,7 +68,7 @@ class CollectionFilter(InAnyFilter, Generic[T]):
|
|
|
70
68
|
|
|
71
69
|
field_name: str
|
|
72
70
|
"""Name of the model attribute to filter on."""
|
|
73
|
-
values: abc.Collection[T]
|
|
71
|
+
values: Optional[abc.Collection[T]]
|
|
74
72
|
"""Values for ``IN`` clause.
|
|
75
73
|
|
|
76
74
|
An empty list will return an empty result set, however, if ``None``, the filter is not applied to the query, and all rows are returned. """
|
|
@@ -82,7 +80,7 @@ class NotInCollectionFilter(InAnyFilter, Generic[T]):
|
|
|
82
80
|
|
|
83
81
|
field_name: str
|
|
84
82
|
"""Name of the model attribute to filter on."""
|
|
85
|
-
values: abc.Collection[T]
|
|
83
|
+
values: Optional[abc.Collection[T]]
|
|
86
84
|
"""Values for ``NOT IN`` clause.
|
|
87
85
|
|
|
88
86
|
An empty list or ``None`` will return all rows."""
|
|
@@ -116,11 +114,11 @@ class OrderBy(StatementFilter):
|
|
|
116
114
|
class SearchFilter(StatementFilter):
|
|
117
115
|
"""Data required to construct a ``WHERE field_name LIKE '%' || :value || '%'`` clause."""
|
|
118
116
|
|
|
119
|
-
field_name: str
|
|
117
|
+
field_name: Union[str, set[str]]
|
|
120
118
|
"""Name of the model attribute to search on."""
|
|
121
119
|
value: str
|
|
122
120
|
"""Search value."""
|
|
123
|
-
ignore_case: bool
|
|
121
|
+
ignore_case: Optional[bool] = False
|
|
124
122
|
"""Should the search be case insensitive."""
|
|
125
123
|
|
|
126
124
|
|