sqlspec 0.25.0__py3-none-any.whl → 0.27.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 (199) hide show
  1. sqlspec/__init__.py +7 -15
  2. sqlspec/_serialization.py +256 -24
  3. sqlspec/_typing.py +71 -52
  4. sqlspec/adapters/adbc/_types.py +1 -1
  5. sqlspec/adapters/adbc/adk/__init__.py +5 -0
  6. sqlspec/adapters/adbc/adk/store.py +870 -0
  7. sqlspec/adapters/adbc/config.py +69 -12
  8. sqlspec/adapters/adbc/data_dictionary.py +340 -0
  9. sqlspec/adapters/adbc/driver.py +266 -58
  10. sqlspec/adapters/adbc/litestar/__init__.py +5 -0
  11. sqlspec/adapters/adbc/litestar/store.py +504 -0
  12. sqlspec/adapters/adbc/type_converter.py +153 -0
  13. sqlspec/adapters/aiosqlite/_types.py +1 -1
  14. sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
  15. sqlspec/adapters/aiosqlite/adk/store.py +527 -0
  16. sqlspec/adapters/aiosqlite/config.py +88 -15
  17. sqlspec/adapters/aiosqlite/data_dictionary.py +149 -0
  18. sqlspec/adapters/aiosqlite/driver.py +143 -40
  19. sqlspec/adapters/aiosqlite/litestar/__init__.py +5 -0
  20. sqlspec/adapters/aiosqlite/litestar/store.py +281 -0
  21. sqlspec/adapters/aiosqlite/pool.py +7 -7
  22. sqlspec/adapters/asyncmy/__init__.py +7 -1
  23. sqlspec/adapters/asyncmy/_types.py +2 -2
  24. sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
  25. sqlspec/adapters/asyncmy/adk/store.py +493 -0
  26. sqlspec/adapters/asyncmy/config.py +68 -23
  27. sqlspec/adapters/asyncmy/data_dictionary.py +161 -0
  28. sqlspec/adapters/asyncmy/driver.py +313 -58
  29. sqlspec/adapters/asyncmy/litestar/__init__.py +5 -0
  30. sqlspec/adapters/asyncmy/litestar/store.py +296 -0
  31. sqlspec/adapters/asyncpg/__init__.py +2 -1
  32. sqlspec/adapters/asyncpg/_type_handlers.py +71 -0
  33. sqlspec/adapters/asyncpg/_types.py +11 -7
  34. sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
  35. sqlspec/adapters/asyncpg/adk/store.py +450 -0
  36. sqlspec/adapters/asyncpg/config.py +59 -35
  37. sqlspec/adapters/asyncpg/data_dictionary.py +173 -0
  38. sqlspec/adapters/asyncpg/driver.py +170 -25
  39. sqlspec/adapters/asyncpg/litestar/__init__.py +5 -0
  40. sqlspec/adapters/asyncpg/litestar/store.py +253 -0
  41. sqlspec/adapters/bigquery/_types.py +1 -1
  42. sqlspec/adapters/bigquery/adk/__init__.py +5 -0
  43. sqlspec/adapters/bigquery/adk/store.py +576 -0
  44. sqlspec/adapters/bigquery/config.py +27 -10
  45. sqlspec/adapters/bigquery/data_dictionary.py +149 -0
  46. sqlspec/adapters/bigquery/driver.py +368 -142
  47. sqlspec/adapters/bigquery/litestar/__init__.py +5 -0
  48. sqlspec/adapters/bigquery/litestar/store.py +327 -0
  49. sqlspec/adapters/bigquery/type_converter.py +125 -0
  50. sqlspec/adapters/duckdb/_types.py +1 -1
  51. sqlspec/adapters/duckdb/adk/__init__.py +14 -0
  52. sqlspec/adapters/duckdb/adk/store.py +553 -0
  53. sqlspec/adapters/duckdb/config.py +80 -20
  54. sqlspec/adapters/duckdb/data_dictionary.py +163 -0
  55. sqlspec/adapters/duckdb/driver.py +167 -45
  56. sqlspec/adapters/duckdb/litestar/__init__.py +5 -0
  57. sqlspec/adapters/duckdb/litestar/store.py +332 -0
  58. sqlspec/adapters/duckdb/pool.py +4 -4
  59. sqlspec/adapters/duckdb/type_converter.py +133 -0
  60. sqlspec/adapters/oracledb/_numpy_handlers.py +133 -0
  61. sqlspec/adapters/oracledb/_types.py +20 -2
  62. sqlspec/adapters/oracledb/adk/__init__.py +5 -0
  63. sqlspec/adapters/oracledb/adk/store.py +1745 -0
  64. sqlspec/adapters/oracledb/config.py +122 -32
  65. sqlspec/adapters/oracledb/data_dictionary.py +509 -0
  66. sqlspec/adapters/oracledb/driver.py +353 -91
  67. sqlspec/adapters/oracledb/litestar/__init__.py +5 -0
  68. sqlspec/adapters/oracledb/litestar/store.py +767 -0
  69. sqlspec/adapters/oracledb/migrations.py +348 -73
  70. sqlspec/adapters/oracledb/type_converter.py +207 -0
  71. sqlspec/adapters/psqlpy/_type_handlers.py +44 -0
  72. sqlspec/adapters/psqlpy/_types.py +2 -1
  73. sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
  74. sqlspec/adapters/psqlpy/adk/store.py +482 -0
  75. sqlspec/adapters/psqlpy/config.py +46 -17
  76. sqlspec/adapters/psqlpy/data_dictionary.py +172 -0
  77. sqlspec/adapters/psqlpy/driver.py +123 -209
  78. sqlspec/adapters/psqlpy/litestar/__init__.py +5 -0
  79. sqlspec/adapters/psqlpy/litestar/store.py +272 -0
  80. sqlspec/adapters/psqlpy/type_converter.py +102 -0
  81. sqlspec/adapters/psycopg/_type_handlers.py +80 -0
  82. sqlspec/adapters/psycopg/_types.py +2 -1
  83. sqlspec/adapters/psycopg/adk/__init__.py +5 -0
  84. sqlspec/adapters/psycopg/adk/store.py +944 -0
  85. sqlspec/adapters/psycopg/config.py +69 -35
  86. sqlspec/adapters/psycopg/data_dictionary.py +331 -0
  87. sqlspec/adapters/psycopg/driver.py +238 -81
  88. sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
  89. sqlspec/adapters/psycopg/litestar/store.py +554 -0
  90. sqlspec/adapters/sqlite/__init__.py +2 -1
  91. sqlspec/adapters/sqlite/_type_handlers.py +86 -0
  92. sqlspec/adapters/sqlite/_types.py +1 -1
  93. sqlspec/adapters/sqlite/adk/__init__.py +5 -0
  94. sqlspec/adapters/sqlite/adk/store.py +572 -0
  95. sqlspec/adapters/sqlite/config.py +87 -15
  96. sqlspec/adapters/sqlite/data_dictionary.py +149 -0
  97. sqlspec/adapters/sqlite/driver.py +137 -54
  98. sqlspec/adapters/sqlite/litestar/__init__.py +5 -0
  99. sqlspec/adapters/sqlite/litestar/store.py +318 -0
  100. sqlspec/adapters/sqlite/pool.py +18 -9
  101. sqlspec/base.py +45 -26
  102. sqlspec/builder/__init__.py +73 -4
  103. sqlspec/builder/_base.py +162 -89
  104. sqlspec/builder/_column.py +62 -29
  105. sqlspec/builder/_ddl.py +180 -121
  106. sqlspec/builder/_delete.py +5 -4
  107. sqlspec/builder/_dml.py +388 -0
  108. sqlspec/{_sql.py → builder/_factory.py} +53 -94
  109. sqlspec/builder/_insert.py +32 -131
  110. sqlspec/builder/_join.py +375 -0
  111. sqlspec/builder/_merge.py +446 -11
  112. sqlspec/builder/_parsing_utils.py +111 -17
  113. sqlspec/builder/_select.py +1457 -24
  114. sqlspec/builder/_update.py +11 -42
  115. sqlspec/cli.py +307 -194
  116. sqlspec/config.py +252 -67
  117. sqlspec/core/__init__.py +5 -4
  118. sqlspec/core/cache.py +17 -17
  119. sqlspec/core/compiler.py +62 -9
  120. sqlspec/core/filters.py +37 -37
  121. sqlspec/core/hashing.py +9 -9
  122. sqlspec/core/parameters.py +83 -48
  123. sqlspec/core/result.py +102 -46
  124. sqlspec/core/splitter.py +16 -17
  125. sqlspec/core/statement.py +36 -30
  126. sqlspec/core/type_conversion.py +235 -0
  127. sqlspec/driver/__init__.py +7 -6
  128. sqlspec/driver/_async.py +188 -151
  129. sqlspec/driver/_common.py +285 -80
  130. sqlspec/driver/_sync.py +188 -152
  131. sqlspec/driver/mixins/_result_tools.py +20 -236
  132. sqlspec/driver/mixins/_sql_translator.py +4 -4
  133. sqlspec/exceptions.py +75 -7
  134. sqlspec/extensions/adk/__init__.py +53 -0
  135. sqlspec/extensions/adk/_types.py +51 -0
  136. sqlspec/extensions/adk/converters.py +172 -0
  137. sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +144 -0
  138. sqlspec/extensions/adk/migrations/__init__.py +0 -0
  139. sqlspec/extensions/adk/service.py +181 -0
  140. sqlspec/extensions/adk/store.py +536 -0
  141. sqlspec/extensions/aiosql/adapter.py +73 -53
  142. sqlspec/extensions/litestar/__init__.py +21 -4
  143. sqlspec/extensions/litestar/cli.py +54 -10
  144. sqlspec/extensions/litestar/config.py +59 -266
  145. sqlspec/extensions/litestar/handlers.py +46 -17
  146. sqlspec/extensions/litestar/migrations/0001_create_session_table.py +137 -0
  147. sqlspec/extensions/litestar/migrations/__init__.py +3 -0
  148. sqlspec/extensions/litestar/plugin.py +324 -223
  149. sqlspec/extensions/litestar/providers.py +25 -25
  150. sqlspec/extensions/litestar/store.py +265 -0
  151. sqlspec/loader.py +30 -49
  152. sqlspec/migrations/__init__.py +4 -3
  153. sqlspec/migrations/base.py +302 -39
  154. sqlspec/migrations/commands.py +611 -144
  155. sqlspec/migrations/context.py +142 -0
  156. sqlspec/migrations/fix.py +199 -0
  157. sqlspec/migrations/loaders.py +68 -23
  158. sqlspec/migrations/runner.py +543 -107
  159. sqlspec/migrations/tracker.py +237 -21
  160. sqlspec/migrations/utils.py +51 -3
  161. sqlspec/migrations/validation.py +177 -0
  162. sqlspec/protocols.py +66 -36
  163. sqlspec/storage/_utils.py +98 -0
  164. sqlspec/storage/backends/fsspec.py +134 -106
  165. sqlspec/storage/backends/local.py +78 -51
  166. sqlspec/storage/backends/obstore.py +278 -162
  167. sqlspec/storage/registry.py +75 -39
  168. sqlspec/typing.py +16 -84
  169. sqlspec/utils/config_resolver.py +153 -0
  170. sqlspec/utils/correlation.py +4 -5
  171. sqlspec/utils/data_transformation.py +3 -2
  172. sqlspec/utils/deprecation.py +9 -8
  173. sqlspec/utils/fixtures.py +4 -4
  174. sqlspec/utils/logging.py +46 -6
  175. sqlspec/utils/module_loader.py +2 -2
  176. sqlspec/utils/schema.py +288 -0
  177. sqlspec/utils/serializers.py +50 -2
  178. sqlspec/utils/sync_tools.py +21 -17
  179. sqlspec/utils/text.py +1 -2
  180. sqlspec/utils/type_guards.py +111 -20
  181. sqlspec/utils/version.py +433 -0
  182. {sqlspec-0.25.0.dist-info → sqlspec-0.27.0.dist-info}/METADATA +40 -21
  183. sqlspec-0.27.0.dist-info/RECORD +207 -0
  184. sqlspec/builder/mixins/__init__.py +0 -55
  185. sqlspec/builder/mixins/_cte_and_set_ops.py +0 -254
  186. sqlspec/builder/mixins/_delete_operations.py +0 -50
  187. sqlspec/builder/mixins/_insert_operations.py +0 -282
  188. sqlspec/builder/mixins/_join_operations.py +0 -389
  189. sqlspec/builder/mixins/_merge_operations.py +0 -592
  190. sqlspec/builder/mixins/_order_limit_operations.py +0 -152
  191. sqlspec/builder/mixins/_pivot_operations.py +0 -157
  192. sqlspec/builder/mixins/_select_operations.py +0 -936
  193. sqlspec/builder/mixins/_update_operations.py +0 -218
  194. sqlspec/builder/mixins/_where_clause.py +0 -1304
  195. sqlspec-0.25.0.dist-info/RECORD +0 -139
  196. sqlspec-0.25.0.dist-info/licenses/NOTICE +0 -29
  197. {sqlspec-0.25.0.dist-info → sqlspec-0.27.0.dist-info}/WHEEL +0 -0
  198. {sqlspec-0.25.0.dist-info → sqlspec-0.27.0.dist-info}/entry_points.txt +0 -0
  199. {sqlspec-0.25.0.dist-info → sqlspec-0.27.0.dist-info}/licenses/LICENSE +0 -0
@@ -3,11 +3,12 @@
3
3
  import contextlib
4
4
  import logging
5
5
  from contextlib import asynccontextmanager
6
- from typing import TYPE_CHECKING, Any, ClassVar, Optional, TypedDict, Union, cast
6
+ from typing import TYPE_CHECKING, Any, ClassVar, TypedDict, cast
7
7
 
8
8
  import oracledb
9
9
  from typing_extensions import NotRequired
10
10
 
11
+ from sqlspec.adapters.oracledb._numpy_handlers import register_numpy_handlers
11
12
  from sqlspec.adapters.oracledb._types import (
12
13
  OracleAsyncConnection,
13
14
  OracleAsyncConnectionPool,
@@ -23,6 +24,7 @@ from sqlspec.adapters.oracledb.driver import (
23
24
  )
24
25
  from sqlspec.adapters.oracledb.migrations import OracleAsyncMigrationTracker, OracleSyncMigrationTracker
25
26
  from sqlspec.config import AsyncDatabaseConfig, SyncDatabaseConfig
27
+ from sqlspec.typing import NUMPY_INSTALLED
26
28
 
27
29
  if TYPE_CHECKING:
28
30
  from collections.abc import AsyncGenerator, Callable, Generator
@@ -32,12 +34,18 @@ if TYPE_CHECKING:
32
34
  from sqlspec.core.statement import StatementConfig
33
35
 
34
36
 
35
- __all__ = ("OracleAsyncConfig", "OracleConnectionParams", "OraclePoolParams", "OracleSyncConfig")
37
+ __all__ = (
38
+ "OracleAsyncConfig",
39
+ "OracleConnectionParams",
40
+ "OracleDriverFeatures",
41
+ "OraclePoolParams",
42
+ "OracleSyncConfig",
43
+ )
36
44
 
37
45
  logger = logging.getLogger(__name__)
38
46
 
39
47
 
40
- class OracleConnectionParams(TypedDict, total=False):
48
+ class OracleConnectionParams(TypedDict):
41
49
  """OracleDB connection parameters."""
42
50
 
43
51
  dsn: NotRequired[str]
@@ -58,7 +66,7 @@ class OracleConnectionParams(TypedDict, total=False):
58
66
  edition: NotRequired[str]
59
67
 
60
68
 
61
- class OraclePoolParams(OracleConnectionParams, total=False):
69
+ class OraclePoolParams(OracleConnectionParams):
62
70
  """OracleDB pool parameters."""
63
71
 
64
72
  min: NotRequired[int]
@@ -77,6 +85,23 @@ class OraclePoolParams(OracleConnectionParams, total=False):
77
85
  extra: NotRequired[dict[str, Any]]
78
86
 
79
87
 
88
+ class OracleDriverFeatures(TypedDict):
89
+ """Oracle driver feature flags.
90
+
91
+ enable_numpy_vectors: Enable automatic NumPy array ↔ Oracle VECTOR conversion.
92
+ Requires NumPy and Oracle Database 23ai or higher with VECTOR data type support.
93
+ Defaults to True when NumPy is installed.
94
+ Provides automatic bidirectional conversion between NumPy ndarrays and Oracle VECTOR columns.
95
+ Supports float32, float64, int8, and uint8 dtypes.
96
+ enable_lowercase_column_names: Normalize implicit Oracle uppercase column names to lowercase.
97
+ Targets unquoted Oracle identifiers that default to uppercase while preserving quoted case-sensitive aliases.
98
+ Defaults to True for compatibility with schema libraries expecting snake_case fields.
99
+ """
100
+
101
+ enable_numpy_vectors: NotRequired[bool]
102
+ enable_lowercase_column_names: NotRequired[bool]
103
+
104
+
80
105
  class OracleSyncConfig(SyncDatabaseConfig[OracleSyncConnection, "OracleSyncConnectionPool", OracleSyncDriver]):
81
106
  """Configuration for Oracle synchronous database connections."""
82
107
 
@@ -85,24 +110,29 @@ class OracleSyncConfig(SyncDatabaseConfig[OracleSyncConnection, "OracleSyncConne
85
110
  driver_type: ClassVar[type[OracleSyncDriver]] = OracleSyncDriver
86
111
  connection_type: "ClassVar[type[OracleSyncConnection]]" = OracleSyncConnection
87
112
  migration_tracker_type: "ClassVar[type[OracleSyncMigrationTracker]]" = OracleSyncMigrationTracker
113
+ supports_transactional_ddl: ClassVar[bool] = False
88
114
 
89
115
  def __init__(
90
116
  self,
91
117
  *,
92
- pool_config: "Optional[Union[OraclePoolParams, dict[str, Any]]]" = None,
93
- pool_instance: "Optional[OracleSyncConnectionPool]" = None,
94
- migration_config: Optional[dict[str, Any]] = None,
95
- statement_config: "Optional[StatementConfig]" = None,
96
- driver_features: "Optional[dict[str, Any]]" = None,
118
+ pool_config: "OraclePoolParams | dict[str, Any] | None" = None,
119
+ pool_instance: "OracleSyncConnectionPool | None" = None,
120
+ migration_config: dict[str, Any] | None = None,
121
+ statement_config: "StatementConfig | None" = None,
122
+ driver_features: "OracleDriverFeatures | dict[str, Any] | None" = None,
123
+ bind_key: "str | None" = None,
124
+ extension_config: "dict[str, dict[str, Any]] | None" = None,
97
125
  ) -> None:
98
126
  """Initialize Oracle synchronous configuration.
99
127
 
100
128
  Args:
101
- pool_config: Pool configuration parameters
102
- pool_instance: Existing pool instance to use
103
- migration_config: Migration configuration
104
- statement_config: Default SQL statement configuration
105
- driver_features: Optional driver feature configuration
129
+ pool_config: Pool configuration parameters.
130
+ pool_instance: Existing pool instance to use.
131
+ migration_config: Migration configuration.
132
+ statement_config: Default SQL statement configuration.
133
+ driver_features: Optional driver feature configuration (TypedDict or dict).
134
+ bind_key: Optional unique identifier for this configuration.
135
+ extension_config: Extension-specific configuration (e.g., Litestar plugin settings).
106
136
  """
107
137
 
108
138
  processed_pool_config: dict[str, Any] = dict(pool_config) if pool_config else {}
@@ -110,18 +140,43 @@ class OracleSyncConfig(SyncDatabaseConfig[OracleSyncConnection, "OracleSyncConne
110
140
  extras = processed_pool_config.pop("extra")
111
141
  processed_pool_config.update(extras)
112
142
  statement_config = statement_config or oracledb_statement_config
143
+
144
+ processed_driver_features: dict[str, Any] = dict(driver_features) if driver_features else {}
145
+ if "enable_numpy_vectors" not in processed_driver_features:
146
+ processed_driver_features["enable_numpy_vectors"] = NUMPY_INSTALLED
147
+ if "enable_lowercase_column_names" not in processed_driver_features:
148
+ processed_driver_features["enable_lowercase_column_names"] = True
149
+
113
150
  super().__init__(
114
151
  pool_config=processed_pool_config,
115
152
  pool_instance=pool_instance,
116
153
  migration_config=migration_config,
117
154
  statement_config=statement_config,
118
- driver_features=driver_features or {},
155
+ driver_features=processed_driver_features,
156
+ bind_key=bind_key,
157
+ extension_config=extension_config,
119
158
  )
120
159
 
121
160
  def _create_pool(self) -> "OracleSyncConnectionPool":
122
161
  """Create the actual connection pool."""
162
+ config = dict(self.pool_config)
163
+
164
+ if self.driver_features.get("enable_numpy_vectors", False):
165
+ config["session_callback"] = self._init_connection
123
166
 
124
- return oracledb.create_pool(**dict(self.pool_config))
167
+ return oracledb.create_pool(**config)
168
+
169
+ def _init_connection(self, connection: "OracleSyncConnection", tag: str) -> None:
170
+ """Initialize connection with optional NumPy vector support.
171
+
172
+ Args:
173
+ connection: Oracle connection to initialize.
174
+ tag: Connection tag for session state (unused).
175
+ """
176
+ if self.driver_features.get("enable_numpy_vectors", False):
177
+ from sqlspec.adapters.oracledb._numpy_handlers import register_numpy_handlers
178
+
179
+ register_numpy_handlers(connection)
125
180
 
126
181
  def _close_pool(self) -> None:
127
182
  """Close the actual connection pool."""
@@ -155,7 +210,7 @@ class OracleSyncConfig(SyncDatabaseConfig[OracleSyncConnection, "OracleSyncConne
155
210
 
156
211
  @contextlib.contextmanager
157
212
  def provide_session(
158
- self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
213
+ self, *args: Any, statement_config: "StatementConfig | None" = None, **kwargs: Any
159
214
  ) -> "Generator[OracleSyncDriver, None, None]":
160
215
  """Provide a driver session context manager.
161
216
 
@@ -169,7 +224,11 @@ class OracleSyncConfig(SyncDatabaseConfig[OracleSyncConnection, "OracleSyncConne
169
224
  """
170
225
  _ = (args, kwargs) # Mark as intentionally unused
171
226
  with self.provide_connection() as conn:
172
- yield self.driver_type(connection=conn, statement_config=statement_config or self.statement_config)
227
+ yield self.driver_type(
228
+ connection=conn,
229
+ statement_config=statement_config or self.statement_config,
230
+ driver_features=self.driver_features,
231
+ )
173
232
 
174
233
  def provide_pool(self) -> "OracleSyncConnectionPool":
175
234
  """Provide pool instance.
@@ -211,24 +270,29 @@ class OracleAsyncConfig(AsyncDatabaseConfig[OracleAsyncConnection, "OracleAsyncC
211
270
  connection_type: "ClassVar[type[OracleAsyncConnection]]" = OracleAsyncConnection
212
271
  driver_type: ClassVar[type[OracleAsyncDriver]] = OracleAsyncDriver
213
272
  migration_tracker_type: "ClassVar[type[OracleAsyncMigrationTracker]]" = OracleAsyncMigrationTracker
273
+ supports_transactional_ddl: ClassVar[bool] = False
214
274
 
215
275
  def __init__(
216
276
  self,
217
277
  *,
218
- pool_config: "Optional[Union[OraclePoolParams, dict[str, Any]]]" = None,
219
- pool_instance: "Optional[OracleAsyncConnectionPool]" = None,
220
- migration_config: Optional[dict[str, Any]] = None,
221
- statement_config: "Optional[StatementConfig]" = None,
222
- driver_features: "Optional[dict[str, Any]]" = None,
278
+ pool_config: "OraclePoolParams | dict[str, Any] | None" = None,
279
+ pool_instance: "OracleAsyncConnectionPool | None" = None,
280
+ migration_config: dict[str, Any] | None = None,
281
+ statement_config: "StatementConfig | None" = None,
282
+ driver_features: "OracleDriverFeatures | dict[str, Any] | None" = None,
283
+ bind_key: "str | None" = None,
284
+ extension_config: "dict[str, dict[str, Any]] | None" = None,
223
285
  ) -> None:
224
286
  """Initialize Oracle asynchronous configuration.
225
287
 
226
288
  Args:
227
- pool_config: Pool configuration parameters
228
- pool_instance: Existing pool instance to use
229
- migration_config: Migration configuration
230
- statement_config: Default SQL statement configuration
231
- driver_features: Optional driver feature configuration
289
+ pool_config: Pool configuration parameters.
290
+ pool_instance: Existing pool instance to use.
291
+ migration_config: Migration configuration.
292
+ statement_config: Default SQL statement configuration.
293
+ driver_features: Optional driver feature configuration (TypedDict or dict).
294
+ bind_key: Optional unique identifier for this configuration.
295
+ extension_config: Extension-specific configuration (e.g., Litestar plugin settings).
232
296
  """
233
297
 
234
298
  processed_pool_config: dict[str, Any] = dict(pool_config) if pool_config else {}
@@ -236,18 +300,40 @@ class OracleAsyncConfig(AsyncDatabaseConfig[OracleAsyncConnection, "OracleAsyncC
236
300
  extras = processed_pool_config.pop("extra")
237
301
  processed_pool_config.update(extras)
238
302
 
303
+ processed_driver_features: dict[str, Any] = dict(driver_features) if driver_features else {}
304
+ if "enable_numpy_vectors" not in processed_driver_features:
305
+ processed_driver_features["enable_numpy_vectors"] = NUMPY_INSTALLED
306
+ if "enable_lowercase_column_names" not in processed_driver_features:
307
+ processed_driver_features["enable_lowercase_column_names"] = True
308
+
239
309
  super().__init__(
240
310
  pool_config=processed_pool_config,
241
311
  pool_instance=pool_instance,
242
312
  migration_config=migration_config,
243
313
  statement_config=statement_config or oracledb_statement_config,
244
- driver_features=driver_features or {},
314
+ driver_features=processed_driver_features,
315
+ bind_key=bind_key,
316
+ extension_config=extension_config,
245
317
  )
246
318
 
247
319
  async def _create_pool(self) -> "OracleAsyncConnectionPool":
248
320
  """Create the actual async connection pool."""
321
+ config = dict(self.pool_config)
322
+
323
+ if self.driver_features.get("enable_numpy_vectors", False):
324
+ config["session_callback"] = self._init_connection
249
325
 
250
- return oracledb.create_pool_async(**dict(self.pool_config))
326
+ return oracledb.create_pool_async(**config)
327
+
328
+ async def _init_connection(self, connection: "OracleAsyncConnection", tag: str) -> None:
329
+ """Initialize async connection with optional NumPy vector support.
330
+
331
+ Args:
332
+ connection: Oracle async connection to initialize.
333
+ tag: Connection tag for session state (unused).
334
+ """
335
+ if self.driver_features.get("enable_numpy_vectors", False):
336
+ register_numpy_handlers(connection)
251
337
 
252
338
  async def _close_pool(self) -> None:
253
339
  """Close the actual async connection pool."""
@@ -285,7 +371,7 @@ class OracleAsyncConfig(AsyncDatabaseConfig[OracleAsyncConnection, "OracleAsyncC
285
371
 
286
372
  @asynccontextmanager
287
373
  async def provide_session(
288
- self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
374
+ self, *args: Any, statement_config: "StatementConfig | None" = None, **kwargs: Any
289
375
  ) -> "AsyncGenerator[OracleAsyncDriver, None]":
290
376
  """Provide an async driver session context manager.
291
377
 
@@ -299,7 +385,11 @@ class OracleAsyncConfig(AsyncDatabaseConfig[OracleAsyncConnection, "OracleAsyncC
299
385
  """
300
386
  _ = (args, kwargs) # Mark as intentionally unused
301
387
  async with self.provide_connection() as conn:
302
- yield self.driver_type(connection=conn, statement_config=statement_config or self.statement_config)
388
+ yield self.driver_type(
389
+ connection=conn,
390
+ statement_config=statement_config or self.statement_config,
391
+ driver_features=self.driver_features,
392
+ )
303
393
 
304
394
  async def provide_pool(self) -> "OracleAsyncConnectionPool":
305
395
  """Provide async pool instance.