sqlspec 0.7.1__py3-none-any.whl → 0.9.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.

Files changed (54) hide show
  1. sqlspec/__init__.py +15 -0
  2. sqlspec/_serialization.py +16 -2
  3. sqlspec/_typing.py +40 -7
  4. sqlspec/adapters/adbc/__init__.py +7 -0
  5. sqlspec/adapters/adbc/config.py +183 -17
  6. sqlspec/adapters/adbc/driver.py +392 -0
  7. sqlspec/adapters/aiosqlite/__init__.py +5 -1
  8. sqlspec/adapters/aiosqlite/config.py +24 -6
  9. sqlspec/adapters/aiosqlite/driver.py +264 -0
  10. sqlspec/adapters/asyncmy/__init__.py +7 -2
  11. sqlspec/adapters/asyncmy/config.py +71 -11
  12. sqlspec/adapters/asyncmy/driver.py +246 -0
  13. sqlspec/adapters/asyncpg/__init__.py +9 -0
  14. sqlspec/adapters/asyncpg/config.py +102 -25
  15. sqlspec/adapters/asyncpg/driver.py +444 -0
  16. sqlspec/adapters/duckdb/__init__.py +5 -1
  17. sqlspec/adapters/duckdb/config.py +194 -12
  18. sqlspec/adapters/duckdb/driver.py +225 -0
  19. sqlspec/adapters/oracledb/__init__.py +7 -4
  20. sqlspec/adapters/oracledb/config/__init__.py +4 -4
  21. sqlspec/adapters/oracledb/config/_asyncio.py +96 -12
  22. sqlspec/adapters/oracledb/config/_common.py +1 -1
  23. sqlspec/adapters/oracledb/config/_sync.py +96 -12
  24. sqlspec/adapters/oracledb/driver.py +571 -0
  25. sqlspec/adapters/psqlpy/__init__.py +0 -0
  26. sqlspec/adapters/psqlpy/config.py +258 -0
  27. sqlspec/adapters/psqlpy/driver.py +335 -0
  28. sqlspec/adapters/psycopg/__init__.py +16 -0
  29. sqlspec/adapters/psycopg/config/__init__.py +6 -6
  30. sqlspec/adapters/psycopg/config/_async.py +107 -15
  31. sqlspec/adapters/psycopg/config/_common.py +2 -2
  32. sqlspec/adapters/psycopg/config/_sync.py +107 -15
  33. sqlspec/adapters/psycopg/driver.py +578 -0
  34. sqlspec/adapters/sqlite/__init__.py +7 -0
  35. sqlspec/adapters/sqlite/config.py +24 -6
  36. sqlspec/adapters/sqlite/driver.py +305 -0
  37. sqlspec/base.py +565 -63
  38. sqlspec/exceptions.py +30 -0
  39. sqlspec/extensions/litestar/__init__.py +19 -0
  40. sqlspec/extensions/litestar/_utils.py +56 -0
  41. sqlspec/extensions/litestar/config.py +87 -0
  42. sqlspec/extensions/litestar/handlers.py +213 -0
  43. sqlspec/extensions/litestar/plugin.py +105 -11
  44. sqlspec/statement.py +373 -0
  45. sqlspec/typing.py +81 -17
  46. sqlspec/utils/__init__.py +3 -0
  47. sqlspec/utils/fixtures.py +4 -5
  48. sqlspec/utils/sync_tools.py +335 -0
  49. {sqlspec-0.7.1.dist-info → sqlspec-0.9.0.dist-info}/METADATA +4 -1
  50. sqlspec-0.9.0.dist-info/RECORD +61 -0
  51. sqlspec-0.7.1.dist-info/RECORD +0 -46
  52. {sqlspec-0.7.1.dist-info → sqlspec-0.9.0.dist-info}/WHEEL +0 -0
  53. {sqlspec-0.7.1.dist-info → sqlspec-0.9.0.dist-info}/licenses/LICENSE +0 -0
  54. {sqlspec-0.7.1.dist-info → sqlspec-0.9.0.dist-info}/licenses/NOTICE +0 -0
@@ -1,14 +1,12 @@
1
1
  from contextlib import asynccontextmanager
2
- from dataclasses import dataclass
3
- from typing import TYPE_CHECKING, Any, Optional
2
+ from dataclasses import dataclass, field
3
+ from typing import TYPE_CHECKING, Any, Optional, cast
4
4
 
5
5
  from oracledb import create_pool_async as oracledb_create_pool # pyright: ignore[reportUnknownVariableType]
6
6
  from oracledb.connection import AsyncConnection
7
- from oracledb.pool import AsyncConnectionPool
8
7
 
9
- from sqlspec.adapters.oracledb.config._common import (
10
- OracleGenericPoolConfig,
11
- )
8
+ from sqlspec.adapters.oracledb.config._common import OracleGenericPoolConfig
9
+ from sqlspec.adapters.oracledb.driver import OracleAsyncDriver
12
10
  from sqlspec.base import AsyncDatabaseConfig
13
11
  from sqlspec.exceptions import ImproperConfigurationError
14
12
  from sqlspec.typing import dataclass_to_dict
@@ -16,20 +14,22 @@ from sqlspec.typing import dataclass_to_dict
16
14
  if TYPE_CHECKING:
17
15
  from collections.abc import AsyncGenerator, Awaitable
18
16
 
17
+ from oracledb.pool import AsyncConnectionPool
18
+
19
19
 
20
20
  __all__ = (
21
- "OracleAsyncDatabaseConfig",
21
+ "OracleAsyncConfig",
22
22
  "OracleAsyncPoolConfig",
23
23
  )
24
24
 
25
25
 
26
26
  @dataclass
27
- class OracleAsyncPoolConfig(OracleGenericPoolConfig[AsyncConnection, AsyncConnectionPool]):
27
+ class OracleAsyncPoolConfig(OracleGenericPoolConfig["AsyncConnection", "AsyncConnectionPool"]):
28
28
  """Async Oracle Pool Config"""
29
29
 
30
30
 
31
31
  @dataclass
32
- class OracleAsyncDatabaseConfig(AsyncDatabaseConfig[AsyncConnection, AsyncConnectionPool]):
32
+ class OracleAsyncConfig(AsyncDatabaseConfig["AsyncConnection", "AsyncConnectionPool", "OracleAsyncDriver"]):
33
33
  """Oracle Async database Configuration.
34
34
 
35
35
  This class provides the base configuration for Oracle database connections, extending
@@ -49,23 +49,91 @@ class OracleAsyncDatabaseConfig(AsyncDatabaseConfig[AsyncConnection, AsyncConnec
49
49
 
50
50
  If set, the plugin will use the provided pool rather than instantiate one.
51
51
  """
52
+ connection_type: "type[AsyncConnection]" = field(init=False, default_factory=lambda: AsyncConnection)
53
+ """Connection class to use.
54
+
55
+ Defaults to :class:`AsyncConnection`.
56
+ """
57
+ driver_type: "type[OracleAsyncDriver]" = field(init=False, default_factory=lambda: OracleAsyncDriver) # type: ignore[type-abstract,unused-ignore]
58
+ """Driver class to use.
59
+
60
+ Defaults to :class:`OracleAsyncDriver`.
61
+ """
62
+
63
+ @property
64
+ def connection_config_dict(self) -> "dict[str, Any]":
65
+ """Return the connection configuration as a dict.
66
+
67
+ Returns:
68
+ A string keyed dict of config kwargs for the oracledb.connect function.
69
+
70
+ Raises:
71
+ ImproperConfigurationError: If the connection configuration is not provided.
72
+ """
73
+ if self.pool_config:
74
+ # Filter out pool-specific parameters
75
+ pool_only_params = {
76
+ "min",
77
+ "max",
78
+ "increment",
79
+ "timeout",
80
+ "wait_timeout",
81
+ "max_lifetime_session",
82
+ "session_callback",
83
+ }
84
+ return dataclass_to_dict(
85
+ self.pool_config,
86
+ exclude_empty=True,
87
+ convert_nested=False,
88
+ exclude=pool_only_params.union({"pool_instance", "connection_type", "driver_type"}),
89
+ )
90
+ msg = "You must provide a 'pool_config' for this adapter."
91
+ raise ImproperConfigurationError(msg)
52
92
 
53
93
  @property
54
94
  def pool_config_dict(self) -> "dict[str, Any]":
55
95
  """Return the pool configuration as a dict.
56
96
 
97
+ Raises:
98
+ ImproperConfigurationError: If no pool_config is provided but a pool_instance
99
+
57
100
  Returns:
58
101
  A string keyed dict of config kwargs for the Asyncpg :func:`create_pool <oracledb.pool.create_pool>`
59
102
  function.
60
103
  """
61
104
  if self.pool_config is not None:
62
- return dataclass_to_dict(self.pool_config, exclude_empty=True, convert_nested=False)
105
+ return dataclass_to_dict(
106
+ self.pool_config,
107
+ exclude_empty=True,
108
+ convert_nested=False,
109
+ exclude={"pool_instance", "connection_type", "driver_type"},
110
+ )
63
111
  msg = "'pool_config' methods can not be used when a 'pool_instance' is provided."
64
112
  raise ImproperConfigurationError(msg)
65
113
 
114
+ async def create_connection(self) -> "AsyncConnection":
115
+ """Create and return a new oracledb async connection from the pool.
116
+
117
+ Returns:
118
+ An AsyncConnection instance.
119
+
120
+ Raises:
121
+ ImproperConfigurationError: If the connection could not be created.
122
+ """
123
+ try:
124
+ pool = await self.provide_pool()
125
+ return cast("AsyncConnection", await pool.acquire()) # type: ignore[no-any-return,unused-ignore]
126
+ except Exception as e:
127
+ msg = f"Could not configure the Oracle async connection. Error: {e!s}"
128
+ raise ImproperConfigurationError(msg) from e
129
+
66
130
  async def create_pool(self) -> "AsyncConnectionPool":
67
131
  """Return a pool. If none exists yet, create one.
68
132
 
133
+ Raises:
134
+ ImproperConfigurationError: If neither pool_config nor pool_instance are provided,
135
+ or if the pool could not be configured.
136
+
69
137
  Returns:
70
138
  Getter that returns the pool instance used by the plugin.
71
139
  """
@@ -95,9 +163,25 @@ class OracleAsyncDatabaseConfig(AsyncDatabaseConfig[AsyncConnection, AsyncConnec
95
163
  async def provide_connection(self, *args: "Any", **kwargs: "Any") -> "AsyncGenerator[AsyncConnection, None]":
96
164
  """Create a connection instance.
97
165
 
98
- Returns:
99
- A connection instance.
166
+ Yields:
167
+ AsyncConnection: A connection instance.
100
168
  """
101
169
  db_pool = await self.provide_pool(*args, **kwargs)
102
170
  async with db_pool.acquire() as connection: # pyright: ignore[reportUnknownMemberType]
103
171
  yield connection
172
+
173
+ @asynccontextmanager
174
+ async def provide_session(self, *args: "Any", **kwargs: "Any") -> "AsyncGenerator[OracleAsyncDriver, None]":
175
+ """Create and provide a database session.
176
+
177
+ Yields:
178
+ OracleAsyncDriver: A driver instance with an active connection.
179
+ """
180
+ async with self.provide_connection(*args, **kwargs) as connection:
181
+ yield self.driver_type(connection)
182
+
183
+ async def close_pool(self) -> None:
184
+ """Close the connection pool."""
185
+ if self.pool_instance is not None:
186
+ await self.pool_instance.close()
187
+ self.pool_instance = None
@@ -27,7 +27,7 @@ PoolT = TypeVar("PoolT", bound="Union[ConnectionPool, AsyncConnectionPool]")
27
27
 
28
28
 
29
29
  @dataclass
30
- class OracleGenericPoolConfig(Generic[ConnectionT, PoolT], GenericPoolConfig):
30
+ class OracleGenericPoolConfig(GenericPoolConfig, Generic[ConnectionT, PoolT]):
31
31
  """Configuration for Oracle database connection pools.
32
32
 
33
33
  This class provides configuration options for both synchronous and asynchronous Oracle
@@ -1,35 +1,35 @@
1
1
  from contextlib import contextmanager
2
- from dataclasses import dataclass
2
+ from dataclasses import dataclass, field
3
3
  from typing import TYPE_CHECKING, Any, Optional
4
4
 
5
5
  from oracledb import create_pool as oracledb_create_pool # pyright: ignore[reportUnknownVariableType]
6
6
  from oracledb.connection import Connection
7
- from oracledb.pool import ConnectionPool
8
7
 
9
- from sqlspec.adapters.oracledb.config._common import (
10
- OracleGenericPoolConfig,
11
- )
8
+ from sqlspec.adapters.oracledb.config._common import OracleGenericPoolConfig
9
+ from sqlspec.adapters.oracledb.driver import OracleSyncDriver
12
10
  from sqlspec.base import SyncDatabaseConfig
13
11
  from sqlspec.exceptions import ImproperConfigurationError
14
12
  from sqlspec.typing import dataclass_to_dict
15
13
 
16
14
  if TYPE_CHECKING:
17
15
  from collections.abc import Generator
18
- from typing import Any
16
+
17
+ from oracledb.pool import ConnectionPool
18
+
19
19
 
20
20
  __all__ = (
21
- "OracleSyncDatabaseConfig",
21
+ "OracleSyncConfig",
22
22
  "OracleSyncPoolConfig",
23
23
  )
24
24
 
25
25
 
26
26
  @dataclass
27
- class OracleSyncPoolConfig(OracleGenericPoolConfig[Connection, ConnectionPool]):
27
+ class OracleSyncPoolConfig(OracleGenericPoolConfig["Connection", "ConnectionPool"]):
28
28
  """Sync Oracle Pool Config"""
29
29
 
30
30
 
31
31
  @dataclass
32
- class OracleSyncDatabaseConfig(SyncDatabaseConfig[Connection, ConnectionPool]):
32
+ class OracleSyncConfig(SyncDatabaseConfig["Connection", "ConnectionPool", "OracleSyncDriver"]):
33
33
  """Oracle Sync database Configuration.
34
34
 
35
35
  This class provides the base configuration for Oracle database connections, extending
@@ -49,23 +49,91 @@ class OracleSyncDatabaseConfig(SyncDatabaseConfig[Connection, ConnectionPool]):
49
49
 
50
50
  If set, the plugin will use the provided pool rather than instantiate one.
51
51
  """
52
+ connection_type: "type[Connection]" = field(init=False, default_factory=lambda: Connection) # pyright: ignore
53
+ """Connection class to use.
54
+
55
+ Defaults to :class:`Connection`.
56
+ """
57
+ driver_type: "type[OracleSyncDriver]" = field(init=False, default_factory=lambda: OracleSyncDriver) # type: ignore[type-abstract,unused-ignore]
58
+ """Driver class to use.
59
+
60
+ Defaults to :class:`OracleSyncDriver`.
61
+ """
62
+
63
+ @property
64
+ def connection_config_dict(self) -> "dict[str, Any]":
65
+ """Return the connection configuration as a dict.
66
+
67
+ Returns:
68
+ A string keyed dict of config kwargs for the oracledb.connect function.
69
+
70
+ Raises:
71
+ ImproperConfigurationError: If the connection configuration is not provided.
72
+ """
73
+ if self.pool_config:
74
+ # Filter out pool-specific parameters
75
+ pool_only_params = {
76
+ "min",
77
+ "max",
78
+ "increment",
79
+ "timeout",
80
+ "wait_timeout",
81
+ "max_lifetime_session",
82
+ "session_callback",
83
+ }
84
+ return dataclass_to_dict(
85
+ self.pool_config,
86
+ exclude_empty=True,
87
+ convert_nested=False,
88
+ exclude=pool_only_params.union({"pool_instance", "connection_type", "driver_type"}),
89
+ )
90
+ msg = "You must provide a 'pool_config' for this adapter."
91
+ raise ImproperConfigurationError(msg)
52
92
 
53
93
  @property
54
94
  def pool_config_dict(self) -> "dict[str, Any]":
55
95
  """Return the pool configuration as a dict.
56
96
 
97
+ Raises:
98
+ ImproperConfigurationError: If no pool_config is provided but a pool_instance
99
+
57
100
  Returns:
58
101
  A string keyed dict of config kwargs for the Asyncpg :func:`create_pool <oracledb.pool.create_pool>`
59
102
  function.
60
103
  """
61
104
  if self.pool_config:
62
- return dataclass_to_dict(self.pool_config, exclude_empty=True, convert_nested=False)
105
+ return dataclass_to_dict(
106
+ self.pool_config,
107
+ exclude_empty=True,
108
+ convert_nested=False,
109
+ exclude={"pool_instance", "connection_type", "driver_type"},
110
+ )
63
111
  msg = "'pool_config' methods can not be used when a 'pool_instance' is provided."
64
112
  raise ImproperConfigurationError(msg)
65
113
 
114
+ def create_connection(self) -> "Connection":
115
+ """Create and return a new oracledb connection from the pool.
116
+
117
+ Returns:
118
+ A Connection instance.
119
+
120
+ Raises:
121
+ ImproperConfigurationError: If the connection could not be created.
122
+ """
123
+ try:
124
+ pool = self.provide_pool()
125
+ return pool.acquire()
126
+ except Exception as e:
127
+ msg = f"Could not configure the Oracle connection. Error: {e!s}"
128
+ raise ImproperConfigurationError(msg) from e
129
+
66
130
  def create_pool(self) -> "ConnectionPool":
67
131
  """Return a pool. If none exists yet, create one.
68
132
 
133
+ Raises:
134
+ ImproperConfigurationError: If neither pool_config nor pool_instance is provided,
135
+ or if the pool could not be configured.
136
+
69
137
  Returns:
70
138
  Getter that returns the pool instance used by the plugin.
71
139
  """
@@ -95,9 +163,25 @@ class OracleSyncDatabaseConfig(SyncDatabaseConfig[Connection, ConnectionPool]):
95
163
  def provide_connection(self, *args: "Any", **kwargs: "Any") -> "Generator[Connection, None, None]":
96
164
  """Create a connection instance.
97
165
 
98
- Returns:
99
- A connection instance.
166
+ Yields:
167
+ Connection: A connection instance from the pool.
100
168
  """
101
169
  db_pool = self.provide_pool(*args, **kwargs)
102
170
  with db_pool.acquire() as connection: # pyright: ignore[reportUnknownMemberType]
103
171
  yield connection
172
+
173
+ @contextmanager
174
+ def provide_session(self, *args: "Any", **kwargs: "Any") -> "Generator[OracleSyncDriver, None, None]":
175
+ """Create and provide a database session.
176
+
177
+ Yields:
178
+ OracleSyncDriver: A driver instance with an active connection.
179
+ """
180
+ with self.provide_connection(*args, **kwargs) as connection:
181
+ yield self.driver_type(connection)
182
+
183
+ def close_pool(self) -> None:
184
+ """Close the connection pool."""
185
+ if self.pool_instance is not None:
186
+ self.pool_instance.close()
187
+ self.pool_instance = None