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.

@@ -1,12 +1,9 @@
1
- from __future__ import annotations
2
-
3
1
  from contextlib import asynccontextmanager
4
2
  from dataclasses import dataclass
5
- from typing import TYPE_CHECKING, Any, TypeVar, Union
3
+ from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union
6
4
 
7
5
  from asyncpg import Record
8
6
  from asyncpg import create_pool as asyncpg_create_pool
9
- from asyncpg.connection import Connection
10
7
  from asyncpg.pool import Pool, PoolConnectionProxy
11
8
  from typing_extensions import TypeAlias
12
9
 
@@ -19,6 +16,8 @@ if TYPE_CHECKING:
19
16
  from asyncio import AbstractEventLoop # pyright: ignore[reportAttributeAccessIssue]
20
17
  from collections.abc import AsyncGenerator, Awaitable, Callable, Coroutine
21
18
 
19
+ from asyncpg.connection import Connection
20
+
22
21
 
23
22
  __all__ = (
24
23
  "AsyncPgConfig",
@@ -28,7 +27,7 @@ __all__ = (
28
27
 
29
28
  T = TypeVar("T")
30
29
 
31
- PgConnection: TypeAlias = Union[Connection, PoolConnectionProxy]
30
+ PgConnection: TypeAlias = "Union[Connection, PoolConnectionProxy]" # pyright: ignore[reportMissingTypeArgument]
32
31
 
33
32
 
34
33
  @dataclass
@@ -41,57 +40,57 @@ class AsyncPgPoolConfig(GenericPoolConfig):
41
40
  dsn: str
42
41
  """Connection arguments specified using as a single string in the following format: ``postgres://user:pass@host:port/database?option=value``
43
42
  """
44
- connect_kwargs: dict[Any, Any] | None | EmptyType = Empty
43
+ connect_kwargs: "Optional[Union[dict[Any, Any], EmptyType]]" = Empty
45
44
  """A dictionary of arguments which will be passed directly to the ``connect()`` method as keyword arguments.
46
45
  """
47
- connection_class: type[Connection] | None | EmptyType = Empty
46
+ connection_class: "Optional[Union[type[Connection], EmptyType]]" = Empty # pyright: ignore[reportMissingTypeArgument]
48
47
  """The class to use for connections. Must be a subclass of Connection
49
48
  """
50
- record_class: type[Record] | EmptyType = Empty
49
+ record_class: "Union[type[Record], EmptyType]" = Empty
51
50
  """If specified, the class to use for records returned by queries on the connections in this pool. Must be a subclass of Record."""
52
51
 
53
- min_size: int | EmptyType = Empty
52
+ min_size: "Union[int, EmptyType]" = Empty
54
53
  """The number of connections to keep open inside the connection pool."""
55
- max_size: int | EmptyType = Empty
54
+ max_size: "Union[int, EmptyType]" = Empty
56
55
  """The number of connections to allow in connection pool “overflow”, that is connections that can be opened above
57
56
  and beyond the pool_size setting, which defaults to 10."""
58
57
 
59
- max_queries: int | EmptyType = Empty
58
+ max_queries: "Union[int, EmptyType]" = Empty
60
59
  """Number of queries after a connection is closed and replaced with a new connection.
61
60
  """
62
- max_inactive_connection_lifetime: float | EmptyType = Empty
61
+ max_inactive_connection_lifetime: "Union[float, EmptyType]" = Empty
63
62
  """Number of seconds after which inactive connections in the pool will be closed. Pass 0 to disable this mechanism."""
64
63
 
65
- setup: Coroutine[None, type[Connection], Any] | EmptyType = Empty
64
+ setup: "Union[Coroutine[None, type[Connection], Any], EmptyType]" = Empty # pyright: ignore[reportMissingTypeArgument]
66
65
  """A coroutine to prepare a connection right before it is returned from Pool.acquire(). An example use case would be to automatically set up notifications listeners for all connections of a pool."""
67
- init: Coroutine[None, type[Connection], Any] | EmptyType = Empty
66
+ init: "Union[Coroutine[None, type[Connection], Any], EmptyType]" = Empty # pyright: ignore[reportMissingTypeArgument]
68
67
  """A coroutine to prepare a connection right before it is returned from Pool.acquire(). An example use case would be to automatically set up notifications listeners for all connections of a pool."""
69
68
 
70
- loop: AbstractEventLoop | EmptyType = Empty
69
+ loop: "Union[AbstractEventLoop, EmptyType]" = Empty
71
70
  """An asyncio event loop instance. If None, the default event loop will be used."""
72
71
 
73
72
 
74
73
  @dataclass
75
- class AsyncPgConfig(AsyncDatabaseConfig[PgConnection, Pool]):
74
+ class AsyncPgConfig(AsyncDatabaseConfig[PgConnection, Pool]): # pyright: ignore[reportMissingTypeArgument]
76
75
  """Asyncpg Configuration."""
77
76
 
78
- pool_config: AsyncPgPoolConfig | None = None
77
+ pool_config: "Optional[AsyncPgPoolConfig]" = None
79
78
  """Asyncpg Pool configuration"""
80
- json_deserializer: Callable[[str], Any] = decode_json
79
+ json_deserializer: "Callable[[str], Any]" = decode_json
81
80
  """For dialects that support the :class:`JSON <sqlalchemy.types.JSON>` datatype, this is a Python callable that will
82
81
  convert a JSON string to a Python object. By default, this is set to SQLSpec's
83
82
  :attr:`decode_json() <sqlspec._serialization.decode_json>` function."""
84
- json_serializer: Callable[[Any], str] = encode_json
83
+ json_serializer: "Callable[[Any], str]" = encode_json
85
84
  """For dialects that support the JSON datatype, this is a Python callable that will render a given object as JSON.
86
85
  By default, SQLSpec's :attr:`encode_json() <sqlspec._serialization.encode_json>` is used."""
87
- pool_instance: Pool | None = None
86
+ pool_instance: "Optional[Pool[Any]]" = None
88
87
  """Optional pool to use.
89
88
 
90
89
  If set, the plugin will use the provided pool rather than instantiate one.
91
90
  """
92
91
 
93
92
  @property
94
- def pool_config_dict(self) -> dict[str, Any]:
93
+ def pool_config_dict(self) -> "dict[str, Any]":
95
94
  """Return the pool configuration as a dict.
96
95
 
97
96
  Returns:
@@ -103,7 +102,7 @@ class AsyncPgConfig(AsyncDatabaseConfig[PgConnection, Pool]):
103
102
  msg = "'pool_config' methods can not be used when a 'pool_instance' is provided."
104
103
  raise ImproperConfigurationError(msg)
105
104
 
106
- async def create_pool(self) -> Pool:
105
+ async def create_pool(self) -> "Pool": # pyright: ignore[reportMissingTypeArgument,reportUnknownParameterType]
107
106
  """Return a pool. If none exists yet, create one.
108
107
 
109
108
  Returns:
@@ -125,21 +124,21 @@ class AsyncPgConfig(AsyncDatabaseConfig[PgConnection, Pool]):
125
124
  )
126
125
  return self.pool_instance
127
126
 
128
- def provide_pool(self, *args: Any, **kwargs: Any) -> Awaitable[Pool]:
127
+ def provide_pool(self, *args: "Any", **kwargs: "Any") -> "Awaitable[Pool]": # pyright: ignore[reportMissingTypeArgument,reportUnknownParameterType]
129
128
  """Create a pool instance.
130
129
 
131
130
  Returns:
132
131
  A Pool instance.
133
132
  """
134
- return self.create_pool()
133
+ return self.create_pool() # pyright: ignore[reportUnknownMemberType,reportUnknownVariableType]
135
134
 
136
135
  @asynccontextmanager
137
- async def provide_connection(self, *args: Any, **kwargs: Any) -> AsyncGenerator[PoolConnectionProxy, None]:
136
+ async def provide_connection(self, *args: "Any", **kwargs: "Any") -> "AsyncGenerator[PoolConnectionProxy, None]": # pyright: ignore[reportMissingTypeArgument,reportUnknownParameterType]
138
137
  """Create a connection instance.
139
138
 
140
139
  Returns:
141
140
  A connection instance.
142
141
  """
143
- db_pool = await self.provide_pool(*args, **kwargs)
144
- async with db_pool.acquire() as connection:
142
+ db_pool = await self.provide_pool(*args, **kwargs) # pyright: ignore[reportUnknownMemberType,reportUnknownVariableType]
143
+ async with db_pool.acquire() as connection: # pyright: ignore[reportUnknownVariableType]
145
144
  yield connection
@@ -1,10 +1,9 @@
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, cast
3
+ from typing import TYPE_CHECKING, Any, Union, cast
6
4
 
7
5
  from duckdb import DuckDBPyConnection
6
+ from typing_extensions import NotRequired, TypedDict
8
7
 
9
8
  from sqlspec.base import NoPoolSyncConfig
10
9
  from sqlspec.exceptions import ImproperConfigurationError
@@ -17,8 +16,7 @@ if TYPE_CHECKING:
17
16
  __all__ = ("DuckDBConfig", "ExtensionConfig")
18
17
 
19
18
 
20
- @dataclass
21
- class ExtensionConfig:
19
+ class ExtensionConfig(TypedDict):
22
20
  """Configuration for a DuckDB extension.
23
21
 
24
22
  This class provides configuration options for DuckDB extensions, including installation
@@ -29,41 +27,17 @@ class ExtensionConfig:
29
27
 
30
28
  name: str
31
29
  """The name of the extension to install"""
32
- config: dict[str, Any] | None = None
30
+ config: "NotRequired[dict[str, Any]]"
33
31
  """Optional configuration settings to apply after installation"""
34
- force_install: bool = False
32
+ force_install: "NotRequired[bool]"
35
33
  """Whether to force reinstall if already present"""
36
- repository: str | None = None
34
+ repository: "NotRequired[str]"
37
35
  """Optional repository name to install from"""
38
- repository_url: str | None = None
36
+ repository_url: "NotRequired[str]"
39
37
  """Optional repository URL to install from"""
40
- version: str | None = None
38
+ version: "NotRequired[str]"
41
39
  """Optional version of the extension to install"""
42
40
 
43
- @classmethod
44
- def from_dict(cls, name: str, config: dict[str, Any] | bool | None = None) -> ExtensionConfig:
45
- """Create an ExtensionConfig from a configuration dictionary.
46
-
47
- Args:
48
- name: The name of the extension
49
- config: Configuration dictionary that may contain settings
50
-
51
- Returns:
52
- A new ExtensionConfig instance
53
- """
54
- if config is None:
55
- return cls(name=name)
56
-
57
- if not isinstance(config, dict):
58
- config = {"force_install": bool(config)}
59
-
60
- install_args = {
61
- key: config.pop(key)
62
- for key in ["force_install", "repository", "repository_url", "version", "config", "name"]
63
- if key in config
64
- }
65
- return cls(name=name, **install_args)
66
-
67
41
 
68
42
  @dataclass
69
43
  class DuckDBConfig(NoPoolSyncConfig[DuckDBPyConnection]):
@@ -75,28 +49,24 @@ class DuckDBConfig(NoPoolSyncConfig[DuckDBPyConnection]):
75
49
  For details see: https://duckdb.org/docs/api/python/overview#connection-options
76
50
  """
77
51
 
78
- database: str | EmptyType = Empty
52
+ database: "Union[str, EmptyType]" = Empty
79
53
  """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. If not specified, an in-memory database will be created."""
80
54
 
81
- read_only: bool | EmptyType = Empty
55
+ read_only: "Union[bool, EmptyType]" = Empty
82
56
  """If True, the database will be opened in read-only mode. This is required if multiple processes want to access the same database file at the same time."""
83
57
 
84
- config: dict[str, Any] | EmptyType = Empty
58
+ config: "Union[dict[str, Any], EmptyType]" = Empty
85
59
  """A dictionary of configuration options to be passed to DuckDB. These can include settings like 'access_mode', 'max_memory', 'threads', etc.
86
60
 
87
61
  For details see: https://duckdb.org/docs/api/python/overview#connection-options
88
62
  """
89
63
 
90
- extensions: Sequence[ExtensionConfig] | EmptyType = Empty
64
+ extensions: "Union[Sequence[ExtensionConfig], ExtensionConfig, EmptyType]" = Empty
91
65
  """A sequence of extension configurations to install and configure upon connection creation."""
92
66
 
93
67
  def __post_init__(self) -> None:
94
68
  """Post-initialization validation and processing.
95
69
 
96
- This method handles merging extension configurations from both the extensions field
97
- and the config dictionary, if present. The config['extensions'] field can be either:
98
- - A dictionary mapping extension names to their configurations
99
- - A list of extension names (which will be installed with force_install=True)
100
70
 
101
71
  Raises:
102
72
  ImproperConfigurationError: If there are duplicate extension configurations.
@@ -106,56 +76,81 @@ class DuckDBConfig(NoPoolSyncConfig[DuckDBPyConnection]):
106
76
 
107
77
  if self.extensions is Empty:
108
78
  self.extensions = []
79
+ if isinstance(self.extensions, dict):
80
+ self.extensions = [self.extensions]
109
81
  # this is purely for mypy
110
82
  assert isinstance(self.config, dict) # noqa: S101
111
83
  assert isinstance(self.extensions, list) # noqa: S101
84
+ config_exts: list[ExtensionConfig] = self.config.pop("extensions", [])
85
+ if not isinstance(config_exts, list): # pyright: ignore[reportUnnecessaryIsInstance]
86
+ config_exts = [config_exts] # type: ignore[unreachable]
112
87
 
113
- _e = self.config.pop("extensions", {})
114
- if not isinstance(_e, (dict, list, tuple)):
88
+ try:
89
+ if (
90
+ len(set({ext["name"] for ext in config_exts}).intersection({ext["name"] for ext in self.extensions}))
91
+ > 0
92
+ ): # pyright: ignore[ reportUnknownArgumentType]
93
+ msg = "Configuring the same extension in both 'extensions' and as a key in 'config['extensions']' is not allowed. Please use only one method to configure extensions."
94
+ raise ImproperConfigurationError(msg)
95
+ except (KeyError, TypeError) as e:
115
96
  msg = "When configuring extensions in the 'config' dictionary, the value must be a dictionary or sequence of extension names"
116
- raise ImproperConfigurationError(msg)
117
- if not isinstance(_e, dict):
118
- _e = {str(ext): {"force_install": False} for ext in _e} # pyright: ignore[reportUnknownVariableType,reportUnknownArgumentType]
97
+ raise ImproperConfigurationError(msg) from e
98
+ self.extensions.extend(config_exts)
119
99
 
120
- if len(set(_e.keys()).intersection({ext.name for ext in self.extensions})) > 0: # pyright: ignore[ reportUnknownArgumentType]
121
- msg = "Configuring the same extension in both 'extensions' and as a key in 'config['extensions']' is not allowed"
122
- raise ImproperConfigurationError(msg)
100
+ def _configure_connection(self, connection: "DuckDBPyConnection") -> None:
101
+ """Configure the connection.
123
102
 
124
- self.extensions.extend([ExtensionConfig.from_dict(name, ext_config) for name, ext_config in _e.items()]) # pyright: ignore[reportUnknownArgumentType,reportUnknownVariableType]
103
+ Args:
104
+ connection: The DuckDB connection to configure.
105
+ """
106
+ for config in cast("list[str]", self.config):
107
+ connection.execute(config)
125
108
 
126
- def _configure_extensions(self, connection: DuckDBPyConnection) -> None:
109
+ def _configure_extensions(self, connection: "DuckDBPyConnection") -> None:
127
110
  """Configure extensions for the connection.
128
111
 
129
112
  Args:
130
113
  connection: The DuckDB connection to configure extensions for.
131
114
 
132
- Raises:
133
- ImproperConfigurationError: If extension installation or configuration fails.
115
+
134
116
  """
135
117
  if self.extensions is Empty:
136
118
  return
137
119
 
138
120
  for extension in cast("list[ExtensionConfig]", self.extensions):
139
- try:
140
- if extension.force_install:
141
- connection.install_extension(
142
- extension=extension.name,
143
- force_install=extension.force_install,
144
- repository=extension.repository,
145
- repository_url=extension.repository_url,
146
- version=extension.version,
147
- )
148
- connection.load_extension(extension.name)
149
-
150
- if extension.config:
151
- for key, value in extension.config.items():
152
- connection.execute(f"SET {key}={value}")
153
- except Exception as e:
154
- msg = f"Failed to configure extension {extension.name}. Error: {e!s}"
155
- raise ImproperConfigurationError(msg) from e
121
+ self._configure_extension(connection, extension)
122
+
123
+ @staticmethod
124
+ def _configure_extension(connection: "DuckDBPyConnection", extension: ExtensionConfig) -> None:
125
+ """Configure a single extension for the connection.
126
+
127
+ Args:
128
+ connection: The DuckDB connection to configure extension for.
129
+ extension: The extension configuration to apply.
130
+
131
+ Raises:
132
+ ImproperConfigurationError: If extension installation or configuration fails.
133
+ """
134
+ try:
135
+ if extension.get("force_install"):
136
+ connection.install_extension(
137
+ extension=extension["name"],
138
+ force_install=extension.get("force_install", False),
139
+ repository=extension.get("repository"),
140
+ repository_url=extension.get("repository_url"),
141
+ version=extension.get("version"),
142
+ )
143
+ connection.load_extension(extension["name"])
144
+
145
+ if extension.get("config"):
146
+ for key, value in extension.get("config", {}).items():
147
+ connection.execute(f"SET {key}={value}")
148
+ except Exception as e:
149
+ msg = f"Failed to configure extension {extension['name']}. Error: {e!s}"
150
+ raise ImproperConfigurationError(msg) from e
156
151
 
157
152
  @property
158
- def connection_config_dict(self) -> dict[str, Any]:
153
+ def connection_config_dict(self) -> "dict[str, Any]":
159
154
  """Return the connection configuration as a dict.
160
155
 
161
156
  Returns:
@@ -166,7 +161,7 @@ class DuckDBConfig(NoPoolSyncConfig[DuckDBPyConnection]):
166
161
  config["database"] = ":memory:"
167
162
  return config
168
163
 
169
- def create_connection(self) -> DuckDBPyConnection:
164
+ def create_connection(self) -> "DuckDBPyConnection":
170
165
  """Create and return a new database connection with configured extensions.
171
166
 
172
167
  Returns:
@@ -180,20 +175,21 @@ class DuckDBConfig(NoPoolSyncConfig[DuckDBPyConnection]):
180
175
  try:
181
176
  connection = duckdb.connect(**self.connection_config_dict) # pyright: ignore[reportUnknownMemberType]
182
177
  self._configure_extensions(connection)
183
- return connection
178
+ self._configure_connection(connection)
184
179
  except Exception as e:
185
180
  msg = f"Could not configure the DuckDB connection. Error: {e!s}"
186
181
  raise ImproperConfigurationError(msg) from e
182
+ else:
183
+ return connection
187
184
 
188
185
  @contextmanager
189
- def provide_connection(self, *args: Any, **kwargs: Any) -> Generator[DuckDBPyConnection, None, None]:
186
+ def provide_connection(self, *args: Any, **kwargs: Any) -> "Generator[DuckDBPyConnection, None, None]":
190
187
  """Create and provide a database connection.
191
188
 
192
189
  Yields:
193
190
  A DuckDB connection instance.
194
191
 
195
- Raises:
196
- ImproperConfigurationError: If the connection could not be established.
192
+
197
193
  """
198
194
  connection = self.create_connection()
199
195
  try:
@@ -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 oracledb import create_pool_async as oracledb_create_pool # pyright: ignore[reportUnknownVariableType]
8
6
  from oracledb.connection import AsyncConnection
@@ -17,7 +15,7 @@ from sqlspec.typing import dataclass_to_dict
17
15
 
18
16
  if TYPE_CHECKING:
19
17
  from collections.abc import AsyncGenerator, Awaitable
20
- from typing import Any
18
+
21
19
 
22
20
  __all__ = (
23
21
  "OracleAsyncDatabaseConfig",
@@ -44,16 +42,16 @@ class OracleAsyncDatabaseConfig(AsyncDatabaseConfig[AsyncConnection, AsyncConnec
44
42
  options.([2](https://python-oracledb.readthedocs.io/en/latest/user_guide/tuning.html))
45
43
  """
46
44
 
47
- pool_config: OracleAsyncPoolConfig | None = None
45
+ pool_config: "Optional[OracleAsyncPoolConfig]" = None
48
46
  """Oracle Pool configuration"""
49
- pool_instance: AsyncConnectionPool | None = None
47
+ pool_instance: "Optional[AsyncConnectionPool]" = 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 OracleAsyncDatabaseConfig(AsyncDatabaseConfig[AsyncConnection, AsyncConnec
65
63
  msg = "'pool_config' methods can not be used when a 'pool_instance' is provided."
66
64
  raise ImproperConfigurationError(msg)
67
65
 
68
- async def create_pool(self) -> AsyncConnectionPool:
66
+ async def create_pool(self) -> "AsyncConnectionPool":
69
67
  """Return a pool. If none exists yet, create one.
70
68
 
71
69
  Returns:
@@ -81,11 +79,11 @@ class OracleAsyncDatabaseConfig(AsyncDatabaseConfig[AsyncConnection, AsyncConnec
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) -> Awaitable[AsyncConnectionPool]:
86
+ def provide_pool(self, *args: "Any", **kwargs: "Any") -> "Awaitable[AsyncConnectionPool]":
89
87
  """Create a pool instance.
90
88
 
91
89
  Returns:
@@ -94,7 +92,7 @@ class OracleAsyncDatabaseConfig(AsyncDatabaseConfig[AsyncConnection, AsyncConnec
94
92
  return self.create_pool()
95
93
 
96
94
  @asynccontextmanager
97
- async def provide_connection(self, *args: Any, **kwargs: Any) -> AsyncGenerator[AsyncConnection, None]:
95
+ async def provide_connection(self, *args: "Any", **kwargs: "Any") -> "AsyncGenerator[AsyncConnection, None]":
98
96
  """Create a connection instance.
99
97
 
100
98
  Returns:
@@ -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 oracledb import ConnectionPool
7
5
 
@@ -24,8 +22,8 @@ __all__ = ("OracleGenericPoolConfig",)
24
22
 
25
23
  T = TypeVar("T")
26
24
 
27
- ConnectionT = TypeVar("ConnectionT", bound="Connection | AsyncConnection")
28
- PoolT = TypeVar("PoolT", bound="ConnectionPool | AsyncConnectionPool")
25
+ ConnectionT = TypeVar("ConnectionT", bound="Union[Connection, AsyncConnection]")
26
+ PoolT = TypeVar("PoolT", bound="Union[ConnectionPool, AsyncConnectionPool]")
29
27
 
30
28
 
31
29
  @dataclass
@@ -37,97 +35,97 @@ class OracleGenericPoolConfig(Generic[ConnectionT, PoolT], GenericPoolConfig):
37
35
  settings.([1](https://python-oracledb.readthedocs.io/en/latest/api_manual/module.html))
38
36
  """
39
37
 
40
- conn_class: type[ConnectionT] | EmptyType = Empty
38
+ conn_class: "Union[type[ConnectionT], EmptyType]" = Empty
41
39
  """The connection class to use (Connection or AsyncConnection)"""
42
- dsn: str | EmptyType = Empty
40
+ dsn: "Union[str, EmptyType]" = Empty
43
41
  """Connection string for the database """
44
- pool: PoolT | EmptyType = Empty
42
+ pool: "Union[PoolT, EmptyType]" = Empty
45
43
  """Existing pool instance to use"""
46
- params: ConnectParams | EmptyType = Empty
44
+ params: "Union[ConnectParams, EmptyType]" = Empty
47
45
  """Connection parameters object"""
48
- user: str | EmptyType = Empty
46
+ user: "Union[str, EmptyType]" = Empty
49
47
  """Username for database authentication"""
50
- proxy_user: str | EmptyType = Empty
48
+ proxy_user: "Union[str, EmptyType]" = Empty
51
49
  """Name of the proxy user to connect through"""
52
- password: str | EmptyType = Empty
50
+ password: "Union[str, EmptyType]" = Empty
53
51
  """Password for database authentication"""
54
- newpassword: str | EmptyType = Empty
52
+ newpassword: "Union[str, EmptyType]" = Empty
55
53
  """New password for password change operations"""
56
- wallet_password: str | EmptyType = Empty
54
+ wallet_password: "Union[str, EmptyType]" = Empty
57
55
  """Password for accessing Oracle Wallet"""
58
- access_token: str | tuple[str, ...] | Callable[[], str] | EmptyType = Empty
56
+ access_token: "Union[str, tuple[str, ...], Callable[[], str], EmptyType]" = Empty
59
57
  """Token for token-based authentication"""
60
- host: str | EmptyType = Empty
58
+ host: "Union[str, EmptyType]" = Empty
61
59
  """Database server hostname"""
62
- port: int | EmptyType = Empty
60
+ port: "Union[int, EmptyType]" = Empty
63
61
  """Database server port number"""
64
- protocol: str | EmptyType = Empty
62
+ protocol: "Union[str, EmptyType]" = Empty
65
63
  """Network protocol (TCP or TCPS)"""
66
- https_proxy: str | EmptyType = Empty
64
+ https_proxy: "Union[str, EmptyType]" = Empty
67
65
  """HTTPS proxy server address"""
68
- https_proxy_port: int | EmptyType = Empty
66
+ https_proxy_port: "Union[int, EmptyType]" = Empty
69
67
  """HTTPS proxy server port"""
70
- service_name: str | EmptyType = Empty
68
+ service_name: "Union[str, EmptyType]" = Empty
71
69
  """Oracle service name"""
72
- sid: str | EmptyType = Empty
70
+ sid: "Union[str, EmptyType]" = Empty
73
71
  """Oracle System ID (SID)"""
74
- server_type: str | EmptyType = Empty
72
+ server_type: "Union[str, EmptyType]" = Empty
75
73
  """Server type (dedicated, shared, pooled, or drcp)"""
76
- cclass: str | EmptyType = Empty
74
+ cclass: "Union[str, EmptyType]" = Empty
77
75
  """Connection class for database resident connection pooling"""
78
- purity: Purity | EmptyType = Empty
76
+ purity: "Union[Purity, EmptyType]" = Empty
79
77
  """Session purity (NEW, SELF, or DEFAULT)"""
80
- expire_time: int | EmptyType = Empty
78
+ expire_time: "Union[int, EmptyType]" = Empty
81
79
  """Time in minutes after which idle connections are closed"""
82
- retry_count: int | EmptyType = Empty
80
+ retry_count: "Union[int, EmptyType]" = Empty
83
81
  """Number of attempts to connect"""
84
- retry_delay: int | EmptyType = Empty
82
+ retry_delay: "Union[int, EmptyType]" = Empty
85
83
  """Time in seconds between connection attempts"""
86
- tcp_connect_timeout: float | EmptyType = Empty
84
+ tcp_connect_timeout: "Union[float, EmptyType]" = Empty
87
85
  """Timeout for establishing TCP connections"""
88
- ssl_server_dn_match: bool | EmptyType = Empty
86
+ ssl_server_dn_match: "Union[bool, EmptyType]" = Empty
89
87
  """If True, verify server certificate DN"""
90
- ssl_server_cert_dn: str | EmptyType = Empty
88
+ ssl_server_cert_dn: "Union[str, EmptyType]" = Empty
91
89
  """Expected server certificate DN"""
92
- wallet_location: str | EmptyType = Empty
90
+ wallet_location: "Union[str, EmptyType]" = Empty
93
91
  """Location of Oracle Wallet"""
94
- events: bool | EmptyType = Empty
92
+ events: "Union[bool, EmptyType]" = Empty
95
93
  """If True, enables Oracle events for FAN and RLB"""
96
- externalauth: bool | EmptyType = Empty
94
+ externalauth: "Union[bool, EmptyType]" = Empty
97
95
  """If True, uses external authentication"""
98
- mode: AuthMode | EmptyType = Empty
96
+ mode: "Union[AuthMode, EmptyType]" = Empty
99
97
  """Session mode (SYSDBA, SYSOPER, etc.)"""
100
- disable_oob: bool | EmptyType = Empty
98
+ disable_oob: "Union[bool, EmptyType]" = Empty
101
99
  """If True, disables Oracle out-of-band breaks"""
102
- stmtcachesize: int | EmptyType = Empty
100
+ stmtcachesize: "Union[int, EmptyType]" = Empty
103
101
  """Size of the statement cache"""
104
- edition: str | EmptyType = Empty
102
+ edition: "Union[str, EmptyType]" = Empty
105
103
  """Edition name for edition-based redefinition"""
106
- tag: str | EmptyType = Empty
104
+ tag: "Union[str, EmptyType]" = Empty
107
105
  """Connection pool tag"""
108
- matchanytag: bool | EmptyType = Empty
106
+ matchanytag: "Union[bool, EmptyType]" = Empty
109
107
  """If True, allows connections with different tags"""
110
- config_dir: str | EmptyType = Empty
108
+ config_dir: "Union[str, EmptyType]" = Empty
111
109
  """Directory containing Oracle configuration files"""
112
- appcontext: list[str] | EmptyType = Empty
110
+ appcontext: "Union[list[str], EmptyType]" = Empty
113
111
  """Application context list"""
114
- shardingkey: list[str] | EmptyType = Empty
112
+ shardingkey: "Union[list[str], EmptyType]" = Empty
115
113
  """Sharding key list"""
116
- supershardingkey: list[str] | EmptyType = Empty
114
+ supershardingkey: "Union[list[str], EmptyType]" = Empty
117
115
  """Super sharding key list"""
118
- debug_jdwp: str | EmptyType = Empty
116
+ debug_jdwp: "Union[str, EmptyType]" = Empty
119
117
  """JDWP debugging string"""
120
- connection_id_prefix: str | EmptyType = Empty
118
+ connection_id_prefix: "Union[str, EmptyType]" = Empty
121
119
  """Prefix for connection identifiers"""
122
- ssl_context: Any | EmptyType = Empty
120
+ ssl_context: "Union[Any, EmptyType]" = Empty
123
121
  """SSL context for TCPS connections"""
124
- sdu: int | EmptyType = Empty
122
+ sdu: "Union[int, EmptyType]" = Empty
125
123
  """Session data unit size"""
126
- pool_boundary: str | EmptyType = Empty
124
+ pool_boundary: "Union[str, EmptyType]" = Empty
127
125
  """Connection pool boundary (statement or transaction)"""
128
- use_tcp_fast_open: bool | EmptyType = Empty
126
+ use_tcp_fast_open: "Union[bool, EmptyType]" = Empty
129
127
  """If True, enables TCP Fast Open"""
130
- ssl_version: ssl.TLSVersion | EmptyType = Empty
128
+ ssl_version: "Union[ssl.TLSVersion, EmptyType]" = Empty
131
129
  """SSL/TLS protocol version"""
132
- handle: int | EmptyType = Empty
130
+ handle: "Union[int, EmptyType]" = Empty
133
131
  """Oracle service context handle"""