sqlspec 0.14.1__py3-none-any.whl → 0.16.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 (159) hide show
  1. sqlspec/__init__.py +50 -25
  2. sqlspec/__main__.py +1 -1
  3. sqlspec/__metadata__.py +1 -3
  4. sqlspec/_serialization.py +1 -2
  5. sqlspec/_sql.py +480 -121
  6. sqlspec/_typing.py +278 -142
  7. sqlspec/adapters/adbc/__init__.py +4 -3
  8. sqlspec/adapters/adbc/_types.py +12 -0
  9. sqlspec/adapters/adbc/config.py +115 -260
  10. sqlspec/adapters/adbc/driver.py +462 -367
  11. sqlspec/adapters/aiosqlite/__init__.py +18 -3
  12. sqlspec/adapters/aiosqlite/_types.py +13 -0
  13. sqlspec/adapters/aiosqlite/config.py +199 -129
  14. sqlspec/adapters/aiosqlite/driver.py +230 -269
  15. sqlspec/adapters/asyncmy/__init__.py +18 -3
  16. sqlspec/adapters/asyncmy/_types.py +12 -0
  17. sqlspec/adapters/asyncmy/config.py +80 -168
  18. sqlspec/adapters/asyncmy/driver.py +260 -225
  19. sqlspec/adapters/asyncpg/__init__.py +19 -4
  20. sqlspec/adapters/asyncpg/_types.py +17 -0
  21. sqlspec/adapters/asyncpg/config.py +82 -181
  22. sqlspec/adapters/asyncpg/driver.py +285 -383
  23. sqlspec/adapters/bigquery/__init__.py +17 -3
  24. sqlspec/adapters/bigquery/_types.py +12 -0
  25. sqlspec/adapters/bigquery/config.py +191 -258
  26. sqlspec/adapters/bigquery/driver.py +474 -646
  27. sqlspec/adapters/duckdb/__init__.py +14 -3
  28. sqlspec/adapters/duckdb/_types.py +12 -0
  29. sqlspec/adapters/duckdb/config.py +415 -351
  30. sqlspec/adapters/duckdb/driver.py +343 -413
  31. sqlspec/adapters/oracledb/__init__.py +19 -5
  32. sqlspec/adapters/oracledb/_types.py +14 -0
  33. sqlspec/adapters/oracledb/config.py +123 -379
  34. sqlspec/adapters/oracledb/driver.py +507 -560
  35. sqlspec/adapters/psqlpy/__init__.py +13 -3
  36. sqlspec/adapters/psqlpy/_types.py +11 -0
  37. sqlspec/adapters/psqlpy/config.py +93 -254
  38. sqlspec/adapters/psqlpy/driver.py +505 -234
  39. sqlspec/adapters/psycopg/__init__.py +19 -5
  40. sqlspec/adapters/psycopg/_types.py +17 -0
  41. sqlspec/adapters/psycopg/config.py +143 -403
  42. sqlspec/adapters/psycopg/driver.py +706 -872
  43. sqlspec/adapters/sqlite/__init__.py +14 -3
  44. sqlspec/adapters/sqlite/_types.py +11 -0
  45. sqlspec/adapters/sqlite/config.py +202 -118
  46. sqlspec/adapters/sqlite/driver.py +264 -303
  47. sqlspec/base.py +105 -9
  48. sqlspec/{statement/builder → builder}/__init__.py +12 -14
  49. sqlspec/{statement/builder → builder}/_base.py +120 -55
  50. sqlspec/{statement/builder → builder}/_column.py +17 -6
  51. sqlspec/{statement/builder → builder}/_ddl.py +46 -79
  52. sqlspec/{statement/builder → builder}/_ddl_utils.py +5 -10
  53. sqlspec/{statement/builder → builder}/_delete.py +6 -25
  54. sqlspec/{statement/builder → builder}/_insert.py +18 -65
  55. sqlspec/builder/_merge.py +56 -0
  56. sqlspec/{statement/builder → builder}/_parsing_utils.py +8 -11
  57. sqlspec/{statement/builder → builder}/_select.py +11 -56
  58. sqlspec/{statement/builder → builder}/_update.py +12 -18
  59. sqlspec/{statement/builder → builder}/mixins/__init__.py +10 -14
  60. sqlspec/{statement/builder → builder}/mixins/_cte_and_set_ops.py +48 -59
  61. sqlspec/{statement/builder → builder}/mixins/_insert_operations.py +34 -18
  62. sqlspec/{statement/builder → builder}/mixins/_join_operations.py +1 -3
  63. sqlspec/{statement/builder → builder}/mixins/_merge_operations.py +19 -9
  64. sqlspec/{statement/builder → builder}/mixins/_order_limit_operations.py +3 -3
  65. sqlspec/{statement/builder → builder}/mixins/_pivot_operations.py +4 -8
  66. sqlspec/{statement/builder → builder}/mixins/_select_operations.py +25 -38
  67. sqlspec/{statement/builder → builder}/mixins/_update_operations.py +15 -16
  68. sqlspec/{statement/builder → builder}/mixins/_where_clause.py +210 -137
  69. sqlspec/cli.py +4 -5
  70. sqlspec/config.py +180 -133
  71. sqlspec/core/__init__.py +63 -0
  72. sqlspec/core/cache.py +873 -0
  73. sqlspec/core/compiler.py +396 -0
  74. sqlspec/core/filters.py +830 -0
  75. sqlspec/core/hashing.py +310 -0
  76. sqlspec/core/parameters.py +1209 -0
  77. sqlspec/core/result.py +664 -0
  78. sqlspec/{statement → core}/splitter.py +321 -191
  79. sqlspec/core/statement.py +666 -0
  80. sqlspec/driver/__init__.py +7 -10
  81. sqlspec/driver/_async.py +387 -176
  82. sqlspec/driver/_common.py +527 -289
  83. sqlspec/driver/_sync.py +390 -172
  84. sqlspec/driver/mixins/__init__.py +2 -19
  85. sqlspec/driver/mixins/_result_tools.py +164 -0
  86. sqlspec/driver/mixins/_sql_translator.py +6 -3
  87. sqlspec/exceptions.py +5 -252
  88. sqlspec/extensions/aiosql/adapter.py +93 -96
  89. sqlspec/extensions/litestar/cli.py +1 -1
  90. sqlspec/extensions/litestar/config.py +0 -1
  91. sqlspec/extensions/litestar/handlers.py +15 -26
  92. sqlspec/extensions/litestar/plugin.py +18 -16
  93. sqlspec/extensions/litestar/providers.py +17 -52
  94. sqlspec/loader.py +424 -105
  95. sqlspec/migrations/__init__.py +12 -0
  96. sqlspec/migrations/base.py +92 -68
  97. sqlspec/migrations/commands.py +24 -106
  98. sqlspec/migrations/loaders.py +402 -0
  99. sqlspec/migrations/runner.py +49 -51
  100. sqlspec/migrations/tracker.py +31 -44
  101. sqlspec/migrations/utils.py +64 -24
  102. sqlspec/protocols.py +7 -183
  103. sqlspec/storage/__init__.py +1 -1
  104. sqlspec/storage/backends/base.py +37 -40
  105. sqlspec/storage/backends/fsspec.py +136 -112
  106. sqlspec/storage/backends/obstore.py +138 -160
  107. sqlspec/storage/capabilities.py +5 -4
  108. sqlspec/storage/registry.py +57 -106
  109. sqlspec/typing.py +136 -115
  110. sqlspec/utils/__init__.py +2 -3
  111. sqlspec/utils/correlation.py +0 -3
  112. sqlspec/utils/deprecation.py +6 -6
  113. sqlspec/utils/fixtures.py +6 -6
  114. sqlspec/utils/logging.py +0 -2
  115. sqlspec/utils/module_loader.py +7 -12
  116. sqlspec/utils/singleton.py +0 -1
  117. sqlspec/utils/sync_tools.py +17 -38
  118. sqlspec/utils/text.py +12 -51
  119. sqlspec/utils/type_guards.py +443 -232
  120. {sqlspec-0.14.1.dist-info → sqlspec-0.16.0.dist-info}/METADATA +7 -2
  121. sqlspec-0.16.0.dist-info/RECORD +134 -0
  122. sqlspec/adapters/adbc/transformers.py +0 -108
  123. sqlspec/driver/connection.py +0 -207
  124. sqlspec/driver/mixins/_cache.py +0 -114
  125. sqlspec/driver/mixins/_csv_writer.py +0 -91
  126. sqlspec/driver/mixins/_pipeline.py +0 -508
  127. sqlspec/driver/mixins/_query_tools.py +0 -796
  128. sqlspec/driver/mixins/_result_utils.py +0 -138
  129. sqlspec/driver/mixins/_storage.py +0 -912
  130. sqlspec/driver/mixins/_type_coercion.py +0 -128
  131. sqlspec/driver/parameters.py +0 -138
  132. sqlspec/statement/__init__.py +0 -21
  133. sqlspec/statement/builder/_merge.py +0 -95
  134. sqlspec/statement/cache.py +0 -50
  135. sqlspec/statement/filters.py +0 -625
  136. sqlspec/statement/parameters.py +0 -956
  137. sqlspec/statement/pipelines/__init__.py +0 -210
  138. sqlspec/statement/pipelines/analyzers/__init__.py +0 -9
  139. sqlspec/statement/pipelines/analyzers/_analyzer.py +0 -646
  140. sqlspec/statement/pipelines/context.py +0 -109
  141. sqlspec/statement/pipelines/transformers/__init__.py +0 -7
  142. sqlspec/statement/pipelines/transformers/_expression_simplifier.py +0 -88
  143. sqlspec/statement/pipelines/transformers/_literal_parameterizer.py +0 -1247
  144. sqlspec/statement/pipelines/transformers/_remove_comments_and_hints.py +0 -76
  145. sqlspec/statement/pipelines/validators/__init__.py +0 -23
  146. sqlspec/statement/pipelines/validators/_dml_safety.py +0 -290
  147. sqlspec/statement/pipelines/validators/_parameter_style.py +0 -370
  148. sqlspec/statement/pipelines/validators/_performance.py +0 -714
  149. sqlspec/statement/pipelines/validators/_security.py +0 -967
  150. sqlspec/statement/result.py +0 -435
  151. sqlspec/statement/sql.py +0 -1774
  152. sqlspec/utils/cached_property.py +0 -25
  153. sqlspec/utils/statement_hashing.py +0 -203
  154. sqlspec-0.14.1.dist-info/RECORD +0 -145
  155. /sqlspec/{statement/builder → builder}/mixins/_delete_operations.py +0 -0
  156. {sqlspec-0.14.1.dist-info → sqlspec-0.16.0.dist-info}/WHEEL +0 -0
  157. {sqlspec-0.14.1.dist-info → sqlspec-0.16.0.dist-info}/entry_points.txt +0 -0
  158. {sqlspec-0.14.1.dist-info → sqlspec-0.16.0.dist-info}/licenses/LICENSE +0 -0
  159. {sqlspec-0.14.1.dist-info → sqlspec-0.16.0.dist-info}/licenses/NOTICE +0 -0
sqlspec/cli.py CHANGED
@@ -32,7 +32,7 @@ def get_sqlspec_group() -> "Group":
32
32
  @click.group(name="sqlspec")
33
33
  @click.option(
34
34
  "--config",
35
- help="Dotted path to SQLAlchemy config(s) (e.g. 'myapp.config.sqlspec_configs')",
35
+ help="Dotted path to SQLSpec config(s) (e.g. 'myapp.config.sqlspec_configs')",
36
36
  required=True,
37
37
  type=str,
38
38
  )
@@ -87,7 +87,7 @@ def add_migration_commands(database_group: Optional["Group"] = None) -> "Group":
87
87
  database_group = get_sqlspec_group()
88
88
 
89
89
  bind_key_option = click.option(
90
- "--bind-key", help="Specify which SQLAlchemy config to use by bind key", type=str, default=None
90
+ "--bind-key", help="Specify which SQLSpec config to use by bind key", type=str, default=None
91
91
  )
92
92
  verbose_option = click.option("--verbose", help="Enable verbose output.", type=bool, default=False, is_flag=True)
93
93
  no_prompt_option = click.option(
@@ -103,21 +103,20 @@ def add_migration_commands(database_group: Optional["Group"] = None) -> "Group":
103
103
  def get_config_by_bind_key(
104
104
  ctx: "click.Context", bind_key: Optional[str]
105
105
  ) -> "Union[AsyncDatabaseConfig[Any, Any, Any], SyncDatabaseConfig[Any, Any, Any]]":
106
- """Get the SQLAlchemy config for the specified bind key.
106
+ """Get the SQLSpec config for the specified bind key.
107
107
 
108
108
  Args:
109
109
  ctx: The click context.
110
110
  bind_key: The bind key to get the config for.
111
111
 
112
112
  Returns:
113
- The SQLAlchemy config for the specified bind key.
113
+ The SQLSpec config for the specified bind key.
114
114
  """
115
115
  configs = ctx.obj["configs"]
116
116
  if bind_key is None:
117
117
  return cast("Union[AsyncDatabaseConfig[Any, Any, Any], SyncDatabaseConfig[Any, Any, Any]]", configs[0])
118
118
 
119
119
  for config in configs:
120
- # Check if config has a name or identifier attribute
121
120
  config_name = getattr(config, "name", None) or getattr(config, "bind_key", None)
122
121
  if config_name == bind_key:
123
122
  return cast("Union[AsyncDatabaseConfig[Any, Any, Any], SyncDatabaseConfig[Any, Any, Any]]", config)
sqlspec/config.py CHANGED
@@ -1,21 +1,17 @@
1
1
  from abc import ABC, abstractmethod
2
- from dataclasses import dataclass, field
3
- from typing import TYPE_CHECKING, Any, ClassVar, Generic, Optional, TypeVar, Union
2
+ from typing import TYPE_CHECKING, Any, Callable, ClassVar, Generic, Optional, TypeVar, Union
4
3
 
5
- from sqlspec.typing import ConnectionT, PoolT # pyright: ignore
4
+ from typing_extensions import NotRequired, TypedDict
5
+
6
+ from sqlspec.core.parameters import ParameterStyle, ParameterStyleConfig
7
+ from sqlspec.core.statement import StatementConfig
6
8
  from sqlspec.utils.logging import get_logger
7
9
 
8
10
  if TYPE_CHECKING:
9
11
  from collections.abc import Awaitable
10
12
  from contextlib import AbstractAsyncContextManager, AbstractContextManager
11
13
 
12
- from sqlglot.dialects.dialect import DialectType
13
-
14
- from sqlspec.driver import AsyncDriverAdapterProtocol, SyncDriverAdapterProtocol
15
- from sqlspec.statement.result import StatementResult
16
-
17
-
18
- StatementResultType = Union["StatementResult[dict[str, Any]]", "StatementResult[Any]"]
14
+ from sqlspec.driver import AsyncDriverAdapterBase, SyncDriverAdapterBase
19
15
 
20
16
 
21
17
  __all__ = (
@@ -24,10 +20,9 @@ __all__ = (
24
20
  "ConfigT",
25
21
  "DatabaseConfigProtocol",
26
22
  "DriverT",
27
- "GenericPoolConfig",
23
+ "LifecycleConfig",
28
24
  "NoPoolAsyncConfig",
29
25
  "NoPoolSyncConfig",
30
- "StatementResultType",
31
26
  "SyncConfigT",
32
27
  "SyncDatabaseConfig",
33
28
  )
@@ -38,74 +33,59 @@ ConfigT = TypeVar(
38
33
  "ConfigT",
39
34
  bound="Union[Union[AsyncDatabaseConfig[Any, Any, Any], NoPoolAsyncConfig[Any, Any]], SyncDatabaseConfig[Any, Any, Any], NoPoolSyncConfig[Any, Any]]",
40
35
  )
41
- DriverT = TypeVar("DriverT", bound="Union[SyncDriverAdapterProtocol[Any], AsyncDriverAdapterProtocol[Any]]")
36
+
37
+ # Define TypeVars for Generic classes
38
+ ConnectionT = TypeVar("ConnectionT")
39
+ PoolT = TypeVar("PoolT")
40
+ DriverT = TypeVar("DriverT", bound="Union[SyncDriverAdapterBase, AsyncDriverAdapterBase]")
42
41
 
43
42
  logger = get_logger("config")
44
43
 
45
44
 
46
- @dataclass
47
- class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
48
- """Protocol defining the interface for database configurations."""
45
+ class LifecycleConfig(TypedDict, total=False):
46
+ """Universal lifecycle hooks for all adapters.
49
47
 
50
- is_async: "ClassVar[bool]" = field(init=False, default=False)
51
- supports_connection_pooling: "ClassVar[bool]" = field(init=False, default=False)
52
- supports_native_arrow_import: "ClassVar[bool]" = field(init=False, default=False)
53
- supports_native_arrow_export: "ClassVar[bool]" = field(init=False, default=False)
54
- supports_native_parquet_import: "ClassVar[bool]" = field(init=False, default=False)
55
- supports_native_parquet_export: "ClassVar[bool]" = field(init=False, default=False)
56
- connection_type: "type[ConnectionT]" = field(init=False, repr=False, hash=False, compare=False)
57
- driver_type: "type[DriverT]" = field(init=False, repr=False, hash=False, compare=False)
58
- pool_instance: "Optional[PoolT]" = field(default=None)
59
- default_row_type: "type[Any]" = field(init=False)
60
- migration_config: "dict[str, Any]" = field(default_factory=dict)
61
- """Migration configuration settings."""
62
- _dialect: "DialectType" = field(default=None, init=False, repr=False, hash=False, compare=False)
63
-
64
- # Adapter-level cache configuration
65
- enable_adapter_cache: bool = field(default=True)
66
- """Enable adapter-level SQL compilation caching."""
67
- adapter_cache_size: int = field(default=500)
68
- """Maximum number of compiled SQL statements to cache per adapter."""
69
- enable_prepared_statements: bool = field(default=False)
70
- """Enable prepared statement pooling for supported databases."""
71
- prepared_statement_cache_size: int = field(default=100)
72
- """Maximum number of prepared statements to maintain."""
73
-
74
- supported_parameter_styles: "ClassVar[tuple[str, ...]]" = ()
75
- """Parameter styles supported by this database adapter (e.g., ('qmark', 'named_colon'))."""
76
-
77
- default_parameter_style: "ClassVar[str]" = "none"
78
- """The preferred/native parameter style for this database."""
48
+ Each hook accepts a list of callables to support multiple handlers.
49
+ """
79
50
 
80
- def __hash__(self) -> int:
81
- return id(self)
51
+ on_connection_create: NotRequired[list[Callable[[Any], None]]]
52
+ on_connection_destroy: NotRequired[list[Callable[[Any], None]]]
53
+ on_pool_create: NotRequired[list[Callable[[Any], None]]]
54
+ on_pool_destroy: NotRequired[list[Callable[[Any], None]]]
55
+ on_session_start: NotRequired[list[Callable[[Any], None]]]
56
+ on_session_end: NotRequired[list[Callable[[Any], None]]]
57
+ on_query_start: NotRequired[list[Callable[[str, dict], None]]]
58
+ on_query_complete: NotRequired[list[Callable[[str, dict, Any], None]]]
59
+ on_error: NotRequired[list[Callable[[Exception, str, dict], None]]]
82
60
 
83
- @property
84
- def dialect(self) -> "DialectType":
85
- """Get the SQL dialect type lazily.
86
61
 
87
- This property allows dialect to be set either statically as a class attribute
88
- or dynamically via the _get_dialect() method. If a specific adapter needs
89
- dynamic dialect detection (e.g., ADBC which supports multiple databases),
90
- it can override _get_dialect() to provide custom logic.
62
+ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
63
+ """Protocol defining the interface for database configurations."""
91
64
 
92
- Returns:
93
- The SQL dialect type for this database.
94
- """
95
- if self._dialect is None:
96
- self._dialect = self._get_dialect()
97
- return self._dialect
65
+ __slots__ = ("driver_features", "migration_config", "pool_instance", "statement_config")
66
+ driver_type: "ClassVar[type[Any]]"
67
+ connection_type: "ClassVar[type[Any]]"
68
+ is_async: "ClassVar[bool]" = False
69
+ supports_connection_pooling: "ClassVar[bool]" = False
70
+ supports_native_arrow_import: "ClassVar[bool]" = False
71
+ supports_native_arrow_export: "ClassVar[bool]" = False
72
+ supports_native_parquet_import: "ClassVar[bool]" = False
73
+ supports_native_parquet_export: "ClassVar[bool]" = False
74
+ statement_config: "StatementConfig"
75
+ pool_instance: "Optional[PoolT]"
76
+ migration_config: "dict[str, Any]"
98
77
 
99
- def _get_dialect(self) -> "DialectType":
100
- """Get the dialect for this database configuration.
78
+ def __hash__(self) -> int:
79
+ return id(self)
101
80
 
102
- This method should be overridden by configs that need dynamic dialect detection.
103
- By default, it looks for the dialect on the driver class.
81
+ def __eq__(self, other: object) -> bool:
82
+ if not isinstance(other, type(self)):
83
+ return False
84
+ return bool(self.pool_instance == other.pool_instance and self.migration_config == other.migration_config)
104
85
 
105
- Returns:
106
- The SQL dialect type.
107
- """
108
- return self.driver_type.dialect
86
+ def __repr__(self) -> str:
87
+ parts = ", ".join([f"pool_instance={self.pool_instance!r}", f"migration_config={self.migration_config!r}"])
88
+ return f"{type(self).__name__}({parts})"
109
89
 
110
90
  @abstractmethod
111
91
  def create_connection(self) -> "Union[ConnectionT, Awaitable[ConnectionT]]":
@@ -126,12 +106,6 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
126
106
  """Provide a database session context manager."""
127
107
  raise NotImplementedError
128
108
 
129
- @property
130
- @abstractmethod
131
- def connection_config_dict(self) -> "dict[str, Any]":
132
- """Return the connection configuration as a dict."""
133
- raise NotImplementedError
134
-
135
109
  @abstractmethod
136
110
  def create_pool(self) -> "Union[PoolT, Awaitable[PoolT]]":
137
111
  """Create and return connection pool."""
@@ -159,46 +133,49 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
159
133
  Returns:
160
134
  Dictionary mapping type names to types.
161
135
  """
162
- namespace: dict[str, type[Any]] = {}
136
+ return {}
163
137
 
164
- if hasattr(self, "driver_type") and self.driver_type:
165
- namespace[self.driver_type.__name__] = self.driver_type
166
138
 
167
- namespace[self.__class__.__name__] = self.__class__
168
-
169
- if hasattr(self, "connection_type") and self.connection_type:
170
- connection_type = self.connection_type
171
-
172
- if hasattr(connection_type, "__args__"):
173
- # It's a generic type, extract the actual types
174
- for arg_type in connection_type.__args__: # type: ignore[attr-defined]
175
- if arg_type and hasattr(arg_type, "__name__"):
176
- namespace[arg_type.__name__] = arg_type
177
- elif hasattr(connection_type, "__name__"):
178
- # Regular type
179
- namespace[connection_type.__name__] = connection_type
180
-
181
- return namespace
182
-
183
-
184
- @dataclass
185
139
  class NoPoolSyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
186
140
  """Base class for a sync database configurations that do not implement a pool."""
187
141
 
188
- is_async: "ClassVar[bool]" = field(init=False, default=False)
189
- supports_connection_pooling: "ClassVar[bool]" = field(init=False, default=False)
190
- pool_instance: None = None
142
+ __slots__ = ("connection_config",)
143
+ is_async: "ClassVar[bool]" = False
144
+ supports_connection_pooling: "ClassVar[bool]" = False
145
+
146
+ def __init__(
147
+ self,
148
+ *,
149
+ connection_config: Optional[dict[str, Any]] = None,
150
+ migration_config: "Optional[dict[str, Any]]" = None,
151
+ statement_config: "Optional[StatementConfig]" = None,
152
+ driver_features: "Optional[dict[str, Any]]" = None,
153
+ ) -> None:
154
+ self.pool_instance = None
155
+ self.connection_config = connection_config or {}
156
+ self.migration_config: dict[str, Any] = migration_config if migration_config is not None else {}
157
+
158
+ if statement_config is None:
159
+ default_parameter_config = ParameterStyleConfig(
160
+ default_parameter_style=ParameterStyle.QMARK, supported_parameter_styles={ParameterStyle.QMARK}
161
+ )
162
+ self.statement_config = StatementConfig(dialect="sqlite", parameter_config=default_parameter_config)
163
+ else:
164
+ self.statement_config = statement_config
165
+ self.driver_features = driver_features or {}
191
166
 
192
167
  def create_connection(self) -> ConnectionT:
193
- """Create connection with instrumentation."""
168
+ """Create a database connection."""
194
169
  raise NotImplementedError
195
170
 
196
171
  def provide_connection(self, *args: Any, **kwargs: Any) -> "AbstractContextManager[ConnectionT]":
197
- """Provide connection with instrumentation."""
172
+ """Provide a database connection context manager."""
198
173
  raise NotImplementedError
199
174
 
200
- def provide_session(self, *args: Any, **kwargs: Any) -> "AbstractContextManager[DriverT]":
201
- """Provide session with instrumentation."""
175
+ def provide_session(
176
+ self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
177
+ ) -> "AbstractContextManager[DriverT]":
178
+ """Provide a database session context manager."""
202
179
  raise NotImplementedError
203
180
 
204
181
  def create_pool(self) -> None:
@@ -211,24 +188,47 @@ class NoPoolSyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
211
188
  return None
212
189
 
213
190
 
214
- @dataclass
215
191
  class NoPoolAsyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
216
192
  """Base class for an async database configurations that do not implement a pool."""
217
193
 
218
- is_async: "ClassVar[bool]" = field(init=False, default=True)
219
- supports_connection_pooling: "ClassVar[bool]" = field(init=False, default=False)
220
- pool_instance: None = None
194
+ __slots__ = ("connection_config",)
195
+
196
+ is_async: "ClassVar[bool]" = True
197
+ supports_connection_pooling: "ClassVar[bool]" = False
198
+
199
+ def __init__(
200
+ self,
201
+ *,
202
+ connection_config: "Optional[dict[str, Any]]" = None,
203
+ migration_config: "Optional[dict[str, Any]]" = None,
204
+ statement_config: "Optional[StatementConfig]" = None,
205
+ driver_features: "Optional[dict[str, Any]]" = None,
206
+ ) -> None:
207
+ self.pool_instance = None
208
+ self.connection_config = connection_config or {}
209
+ self.migration_config: dict[str, Any] = migration_config if migration_config is not None else {}
210
+
211
+ if statement_config is None:
212
+ default_parameter_config = ParameterStyleConfig(
213
+ default_parameter_style=ParameterStyle.QMARK, supported_parameter_styles={ParameterStyle.QMARK}
214
+ )
215
+ self.statement_config = StatementConfig(dialect="sqlite", parameter_config=default_parameter_config)
216
+ else:
217
+ self.statement_config = statement_config
218
+ self.driver_features = driver_features or {}
221
219
 
222
220
  async def create_connection(self) -> ConnectionT:
223
- """Create connection with instrumentation."""
221
+ """Create a database connection."""
224
222
  raise NotImplementedError
225
223
 
226
224
  def provide_connection(self, *args: Any, **kwargs: Any) -> "AbstractAsyncContextManager[ConnectionT]":
227
- """Provide connection with instrumentation."""
225
+ """Provide a database connection context manager."""
228
226
  raise NotImplementedError
229
227
 
230
- def provide_session(self, *args: Any, **kwargs: Any) -> "AbstractAsyncContextManager[DriverT]":
231
- """Provide session with instrumentation."""
228
+ def provide_session(
229
+ self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
230
+ ) -> "AbstractAsyncContextManager[DriverT]":
231
+ """Provide a database session context manager."""
232
232
  raise NotImplementedError
233
233
 
234
234
  async def create_pool(self) -> None:
@@ -241,20 +241,38 @@ class NoPoolAsyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
241
241
  return None
242
242
 
243
243
 
244
- @dataclass
245
- class GenericPoolConfig:
246
- """Generic Database Pool Configuration."""
247
-
248
-
249
- @dataclass
250
244
  class SyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
251
245
  """Generic Sync Database Configuration."""
252
246
 
253
- is_async: "ClassVar[bool]" = field(init=False, default=False)
254
- supports_connection_pooling: "ClassVar[bool]" = field(init=False, default=True)
247
+ __slots__ = ("pool_config",)
248
+
249
+ is_async: "ClassVar[bool]" = False
250
+ supports_connection_pooling: "ClassVar[bool]" = True
251
+
252
+ def __init__(
253
+ self,
254
+ *,
255
+ pool_config: "Optional[dict[str, Any]]" = None,
256
+ pool_instance: "Optional[PoolT]" = None,
257
+ migration_config: "Optional[dict[str, Any]]" = None,
258
+ statement_config: "Optional[StatementConfig]" = None,
259
+ driver_features: "Optional[dict[str, Any]]" = None,
260
+ ) -> None:
261
+ self.pool_instance = pool_instance
262
+ self.pool_config = pool_config or {}
263
+ self.migration_config: dict[str, Any] = migration_config if migration_config is not None else {}
264
+
265
+ if statement_config is None:
266
+ default_parameter_config = ParameterStyleConfig(
267
+ default_parameter_style=ParameterStyle.QMARK, supported_parameter_styles={ParameterStyle.QMARK}
268
+ )
269
+ self.statement_config = StatementConfig(dialect="postgres", parameter_config=default_parameter_config)
270
+ else:
271
+ self.statement_config = statement_config
272
+ self.driver_features = driver_features or {}
255
273
 
256
274
  def create_pool(self) -> PoolT:
257
- """Create pool with instrumentation.
275
+ """Create and return the connection pool.
258
276
 
259
277
  Returns:
260
278
  The created pool.
@@ -265,7 +283,7 @@ class SyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
265
283
  return self.pool_instance
266
284
 
267
285
  def close_pool(self) -> None:
268
- """Close pool with instrumentation."""
286
+ """Close the connection pool."""
269
287
  self._close_pool()
270
288
 
271
289
  def provide_pool(self, *args: Any, **kwargs: Any) -> PoolT:
@@ -275,15 +293,17 @@ class SyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
275
293
  return self.pool_instance
276
294
 
277
295
  def create_connection(self) -> ConnectionT:
278
- """Create connection with instrumentation."""
296
+ """Create a database connection."""
279
297
  raise NotImplementedError
280
298
 
281
299
  def provide_connection(self, *args: Any, **kwargs: Any) -> "AbstractContextManager[ConnectionT]":
282
- """Provide connection with instrumentation."""
300
+ """Provide a database connection context manager."""
283
301
  raise NotImplementedError
284
302
 
285
- def provide_session(self, *args: Any, **kwargs: Any) -> "AbstractContextManager[DriverT]":
286
- """Provide session with instrumentation."""
303
+ def provide_session(
304
+ self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
305
+ ) -> "AbstractContextManager[DriverT]":
306
+ """Provide a database session context manager."""
287
307
  raise NotImplementedError
288
308
 
289
309
  @abstractmethod
@@ -297,15 +317,40 @@ class SyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
297
317
  raise NotImplementedError
298
318
 
299
319
 
300
- @dataclass
301
320
  class AsyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
302
321
  """Generic Async Database Configuration."""
303
322
 
304
- is_async: "ClassVar[bool]" = field(init=False, default=True)
305
- supports_connection_pooling: "ClassVar[bool]" = field(init=False, default=True)
323
+ __slots__ = ("pool_config",)
324
+
325
+ is_async: "ClassVar[bool]" = True
326
+ supports_connection_pooling: "ClassVar[bool]" = True
327
+
328
+ def __init__(
329
+ self,
330
+ *,
331
+ pool_config: "Optional[dict[str, Any]]" = None,
332
+ pool_instance: "Optional[PoolT]" = None,
333
+ migration_config: "Optional[dict[str, Any]]" = None,
334
+ statement_config: "Optional[StatementConfig]" = None,
335
+ driver_features: "Optional[dict[str, Any]]" = None,
336
+ ) -> None:
337
+ self.pool_instance = pool_instance
338
+ self.pool_config = pool_config or {}
339
+ self.migration_config: dict[str, Any] = migration_config if migration_config is not None else {}
340
+
341
+ if statement_config is None:
342
+ self.statement_config = StatementConfig(
343
+ parameter_config=ParameterStyleConfig(
344
+ default_parameter_style=ParameterStyle.QMARK, supported_parameter_styles={ParameterStyle.QMARK}
345
+ ),
346
+ dialect="postgres",
347
+ )
348
+ else:
349
+ self.statement_config = statement_config
350
+ self.driver_features = driver_features or {}
306
351
 
307
352
  async def create_pool(self) -> PoolT:
308
- """Create pool with instrumentation.
353
+ """Create and return the connection pool.
309
354
 
310
355
  Returns:
311
356
  The created pool.
@@ -316,7 +361,7 @@ class AsyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
316
361
  return self.pool_instance
317
362
 
318
363
  async def close_pool(self) -> None:
319
- """Close pool with instrumentation."""
364
+ """Close the connection pool."""
320
365
  await self._close_pool()
321
366
 
322
367
  async def provide_pool(self, *args: Any, **kwargs: Any) -> PoolT:
@@ -326,15 +371,17 @@ class AsyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
326
371
  return self.pool_instance
327
372
 
328
373
  async def create_connection(self) -> ConnectionT:
329
- """Create connection with instrumentation."""
374
+ """Create a database connection."""
330
375
  raise NotImplementedError
331
376
 
332
377
  def provide_connection(self, *args: Any, **kwargs: Any) -> "AbstractAsyncContextManager[ConnectionT]":
333
- """Provide connection with instrumentation."""
378
+ """Provide a database connection context manager."""
334
379
  raise NotImplementedError
335
380
 
336
- def provide_session(self, *args: Any, **kwargs: Any) -> "AbstractAsyncContextManager[DriverT]":
337
- """Provide session with instrumentation."""
381
+ def provide_session(
382
+ self, *args: Any, statement_config: "Optional[StatementConfig]" = None, **kwargs: Any
383
+ ) -> "AbstractAsyncContextManager[DriverT]":
384
+ """Provide a database session context manager."""
338
385
  raise NotImplementedError
339
386
 
340
387
  @abstractmethod
@@ -0,0 +1,63 @@
1
+ """SQLSpec Core Module - SQL Processing System.
2
+
3
+ This module provides the core SQL processing components including statement handling,
4
+ parameter processing, compilation, and result management.
5
+
6
+ Components:
7
+ - statement.py: SQL class with StatementConfig
8
+ - parameters.py: Parameter processing pipeline
9
+ - compiler.py: SQL compilation with caching
10
+ - result.py: Result classes for query execution
11
+ - filters.py: Statement filter system
12
+ - cache.py: Unified caching system
13
+ - splitter.py: SQL statement splitter
14
+ - hashing.py: Cache key generation
15
+ """
16
+
17
+ from sqlspec.core import filters
18
+ from sqlspec.core.cache import CacheConfig, CacheStats, UnifiedCache, get_statement_cache
19
+ from sqlspec.core.compiler import OperationType, SQLProcessor
20
+ from sqlspec.core.filters import StatementFilter
21
+ from sqlspec.core.hashing import (
22
+ hash_expression,
23
+ hash_expression_node,
24
+ hash_optimized_expression,
25
+ hash_parameters,
26
+ hash_sql_statement,
27
+ )
28
+ from sqlspec.core.parameters import (
29
+ ParameterConverter,
30
+ ParameterProcessor,
31
+ ParameterStyle,
32
+ ParameterStyleConfig,
33
+ TypedParameter,
34
+ )
35
+ from sqlspec.core.result import ArrowResult, SQLResult, StatementResult
36
+ from sqlspec.core.statement import SQL, Statement, StatementConfig
37
+
38
+ __all__ = (
39
+ "SQL",
40
+ "ArrowResult",
41
+ "CacheConfig",
42
+ "CacheStats",
43
+ "OperationType",
44
+ "ParameterConverter",
45
+ "ParameterProcessor",
46
+ "ParameterStyle",
47
+ "ParameterStyleConfig",
48
+ "SQLProcessor",
49
+ "SQLResult",
50
+ "Statement",
51
+ "StatementConfig",
52
+ "StatementFilter",
53
+ "StatementResult",
54
+ "TypedParameter",
55
+ "UnifiedCache",
56
+ "filters",
57
+ "get_statement_cache",
58
+ "hash_expression",
59
+ "hash_expression_node",
60
+ "hash_optimized_expression",
61
+ "hash_parameters",
62
+ "hash_sql_statement",
63
+ )