sqlspec 0.24.1__py3-none-any.whl → 0.26.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 (95) hide show
  1. sqlspec/_serialization.py +223 -21
  2. sqlspec/_sql.py +20 -62
  3. sqlspec/_typing.py +11 -0
  4. sqlspec/adapters/adbc/config.py +8 -1
  5. sqlspec/adapters/adbc/data_dictionary.py +290 -0
  6. sqlspec/adapters/adbc/driver.py +129 -20
  7. sqlspec/adapters/adbc/type_converter.py +159 -0
  8. sqlspec/adapters/aiosqlite/config.py +3 -0
  9. sqlspec/adapters/aiosqlite/data_dictionary.py +117 -0
  10. sqlspec/adapters/aiosqlite/driver.py +17 -3
  11. sqlspec/adapters/asyncmy/_types.py +1 -1
  12. sqlspec/adapters/asyncmy/config.py +11 -8
  13. sqlspec/adapters/asyncmy/data_dictionary.py +122 -0
  14. sqlspec/adapters/asyncmy/driver.py +31 -7
  15. sqlspec/adapters/asyncpg/config.py +3 -0
  16. sqlspec/adapters/asyncpg/data_dictionary.py +134 -0
  17. sqlspec/adapters/asyncpg/driver.py +19 -4
  18. sqlspec/adapters/bigquery/config.py +3 -0
  19. sqlspec/adapters/bigquery/data_dictionary.py +109 -0
  20. sqlspec/adapters/bigquery/driver.py +21 -3
  21. sqlspec/adapters/bigquery/type_converter.py +93 -0
  22. sqlspec/adapters/duckdb/_types.py +1 -1
  23. sqlspec/adapters/duckdb/config.py +2 -0
  24. sqlspec/adapters/duckdb/data_dictionary.py +124 -0
  25. sqlspec/adapters/duckdb/driver.py +32 -5
  26. sqlspec/adapters/duckdb/pool.py +1 -1
  27. sqlspec/adapters/duckdb/type_converter.py +103 -0
  28. sqlspec/adapters/oracledb/config.py +6 -0
  29. sqlspec/adapters/oracledb/data_dictionary.py +442 -0
  30. sqlspec/adapters/oracledb/driver.py +68 -9
  31. sqlspec/adapters/oracledb/migrations.py +51 -67
  32. sqlspec/adapters/oracledb/type_converter.py +132 -0
  33. sqlspec/adapters/psqlpy/config.py +3 -0
  34. sqlspec/adapters/psqlpy/data_dictionary.py +133 -0
  35. sqlspec/adapters/psqlpy/driver.py +23 -179
  36. sqlspec/adapters/psqlpy/type_converter.py +73 -0
  37. sqlspec/adapters/psycopg/config.py +8 -4
  38. sqlspec/adapters/psycopg/data_dictionary.py +257 -0
  39. sqlspec/adapters/psycopg/driver.py +40 -5
  40. sqlspec/adapters/sqlite/config.py +3 -0
  41. sqlspec/adapters/sqlite/data_dictionary.py +117 -0
  42. sqlspec/adapters/sqlite/driver.py +18 -3
  43. sqlspec/adapters/sqlite/pool.py +13 -4
  44. sqlspec/base.py +3 -4
  45. sqlspec/builder/_base.py +130 -48
  46. sqlspec/builder/_column.py +66 -24
  47. sqlspec/builder/_ddl.py +91 -41
  48. sqlspec/builder/_insert.py +40 -58
  49. sqlspec/builder/_parsing_utils.py +127 -12
  50. sqlspec/builder/_select.py +147 -2
  51. sqlspec/builder/_update.py +1 -1
  52. sqlspec/builder/mixins/_cte_and_set_ops.py +31 -23
  53. sqlspec/builder/mixins/_delete_operations.py +12 -7
  54. sqlspec/builder/mixins/_insert_operations.py +50 -36
  55. sqlspec/builder/mixins/_join_operations.py +15 -30
  56. sqlspec/builder/mixins/_merge_operations.py +210 -78
  57. sqlspec/builder/mixins/_order_limit_operations.py +4 -10
  58. sqlspec/builder/mixins/_pivot_operations.py +1 -0
  59. sqlspec/builder/mixins/_select_operations.py +44 -22
  60. sqlspec/builder/mixins/_update_operations.py +30 -37
  61. sqlspec/builder/mixins/_where_clause.py +52 -70
  62. sqlspec/cli.py +246 -140
  63. sqlspec/config.py +33 -19
  64. sqlspec/core/__init__.py +3 -2
  65. sqlspec/core/cache.py +298 -352
  66. sqlspec/core/compiler.py +61 -4
  67. sqlspec/core/filters.py +246 -213
  68. sqlspec/core/hashing.py +9 -11
  69. sqlspec/core/parameters.py +27 -10
  70. sqlspec/core/statement.py +72 -12
  71. sqlspec/core/type_conversion.py +234 -0
  72. sqlspec/driver/__init__.py +6 -3
  73. sqlspec/driver/_async.py +108 -5
  74. sqlspec/driver/_common.py +186 -17
  75. sqlspec/driver/_sync.py +108 -5
  76. sqlspec/driver/mixins/_result_tools.py +60 -7
  77. sqlspec/exceptions.py +5 -0
  78. sqlspec/loader.py +8 -9
  79. sqlspec/migrations/__init__.py +4 -3
  80. sqlspec/migrations/base.py +153 -14
  81. sqlspec/migrations/commands.py +34 -96
  82. sqlspec/migrations/context.py +145 -0
  83. sqlspec/migrations/loaders.py +25 -8
  84. sqlspec/migrations/runner.py +352 -82
  85. sqlspec/storage/backends/fsspec.py +1 -0
  86. sqlspec/typing.py +4 -0
  87. sqlspec/utils/config_resolver.py +153 -0
  88. sqlspec/utils/serializers.py +50 -2
  89. {sqlspec-0.24.1.dist-info → sqlspec-0.26.0.dist-info}/METADATA +1 -1
  90. sqlspec-0.26.0.dist-info/RECORD +157 -0
  91. sqlspec-0.24.1.dist-info/RECORD +0 -139
  92. {sqlspec-0.24.1.dist-info → sqlspec-0.26.0.dist-info}/WHEEL +0 -0
  93. {sqlspec-0.24.1.dist-info → sqlspec-0.26.0.dist-info}/entry_points.txt +0 -0
  94. {sqlspec-0.24.1.dist-info → sqlspec-0.26.0.dist-info}/licenses/LICENSE +0 -0
  95. {sqlspec-0.24.1.dist-info → sqlspec-0.26.0.dist-info}/licenses/NOTICE +0 -0
sqlspec/config.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import TYPE_CHECKING, Any, Callable, ClassVar, Generic, Optional, TypeVar, Union
2
+ from pathlib import Path
3
+ from typing import TYPE_CHECKING, Any, Callable, ClassVar, Generic, Optional, TypeVar, Union, cast
3
4
 
4
5
  from typing_extensions import NotRequired, TypedDict
5
6
 
@@ -11,11 +12,10 @@ from sqlspec.utils.logging import get_logger
11
12
  if TYPE_CHECKING:
12
13
  from collections.abc import Awaitable
13
14
  from contextlib import AbstractAsyncContextManager, AbstractContextManager
14
- from pathlib import Path
15
15
 
16
16
  from sqlspec.driver import AsyncDriverAdapterBase, SyncDriverAdapterBase
17
17
  from sqlspec.loader import SQLFileLoader
18
- from sqlspec.migrations.commands import MigrationCommands
18
+ from sqlspec.migrations.commands import AsyncMigrationCommands, SyncMigrationCommands
19
19
 
20
20
 
21
21
  __all__ = (
@@ -89,6 +89,7 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
89
89
  __slots__ = (
90
90
  "_migration_commands",
91
91
  "_migration_loader",
92
+ "bind_key",
92
93
  "driver_features",
93
94
  "migration_config",
94
95
  "pool_instance",
@@ -96,7 +97,7 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
96
97
  )
97
98
 
98
99
  _migration_loader: "SQLFileLoader"
99
- _migration_commands: "MigrationCommands"
100
+ _migration_commands: "Union[SyncMigrationCommands, AsyncMigrationCommands]"
100
101
  driver_type: "ClassVar[type[Any]]"
101
102
  connection_type: "ClassVar[type[Any]]"
102
103
  is_async: "ClassVar[bool]" = False
@@ -105,6 +106,7 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
105
106
  supports_native_arrow_export: "ClassVar[bool]" = False
106
107
  supports_native_parquet_import: "ClassVar[bool]" = False
107
108
  supports_native_parquet_export: "ClassVar[bool]" = False
109
+ bind_key: "Optional[str]"
108
110
  statement_config: "StatementConfig"
109
111
  pool_instance: "Optional[PoolT]"
110
112
  migration_config: "Union[dict[str, Any], MigrationConfig]"
@@ -176,10 +178,10 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
176
178
  at runtime when needed.
177
179
  """
178
180
  from sqlspec.loader import SQLFileLoader
179
- from sqlspec.migrations.commands import MigrationCommands
181
+ from sqlspec.migrations.commands import create_migration_commands
180
182
 
181
183
  self._migration_loader = SQLFileLoader()
182
- self._migration_commands = MigrationCommands(self) # type: ignore[arg-type]
184
+ self._migration_commands = create_migration_commands(self) # type: ignore[arg-type]
183
185
 
184
186
  def _ensure_migration_loader(self) -> "SQLFileLoader":
185
187
  """Get the migration SQL loader and auto-load files if needed.
@@ -200,7 +202,7 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
200
202
 
201
203
  return self._migration_loader
202
204
 
203
- def _ensure_migration_commands(self) -> "MigrationCommands":
205
+ def _ensure_migration_commands(self) -> "Union[SyncMigrationCommands, AsyncMigrationCommands]":
204
206
  """Get the migration commands instance.
205
207
 
206
208
  Returns:
@@ -225,7 +227,6 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
225
227
  Args:
226
228
  *paths: One or more file paths or directory paths to load migration SQL files from.
227
229
  """
228
- from pathlib import Path
229
230
 
230
231
  loader = self._ensure_migration_loader()
231
232
  for path in paths:
@@ -236,7 +237,7 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
236
237
  else:
237
238
  logger.warning("Migration path does not exist: %s", path_obj)
238
239
 
239
- def get_migration_commands(self) -> "MigrationCommands":
240
+ def get_migration_commands(self) -> "Union[SyncMigrationCommands, AsyncMigrationCommands]":
240
241
  """Get migration commands for this configuration.
241
242
 
242
243
  Returns:
@@ -244,25 +245,27 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
244
245
  """
245
246
  return self._ensure_migration_commands()
246
247
 
247
- def migrate_up(self, revision: str = "head") -> None:
248
+ async def migrate_up(self, revision: str = "head") -> None:
248
249
  """Apply migrations up to the specified revision.
249
250
 
250
251
  Args:
251
252
  revision: Target revision or "head" for latest. Defaults to "head".
252
253
  """
253
254
  commands = self._ensure_migration_commands()
254
- commands.upgrade(revision)
255
255
 
256
- def migrate_down(self, revision: str = "-1") -> None:
256
+ await cast("AsyncMigrationCommands", commands).upgrade(revision)
257
+
258
+ async def migrate_down(self, revision: str = "-1") -> None:
257
259
  """Apply migrations down to the specified revision.
258
260
 
259
261
  Args:
260
262
  revision: Target revision, "-1" for one step back, or "base" for all migrations. Defaults to "-1".
261
263
  """
262
264
  commands = self._ensure_migration_commands()
263
- commands.downgrade(revision)
264
265
 
265
- def get_current_migration(self, verbose: bool = False) -> "Optional[str]":
266
+ await cast("AsyncMigrationCommands", commands).downgrade(revision)
267
+
268
+ async def get_current_migration(self, verbose: bool = False) -> "Optional[str]":
266
269
  """Get the current migration version.
267
270
 
268
271
  Args:
@@ -272,9 +275,10 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
272
275
  Current migration version or None if no migrations applied.
273
276
  """
274
277
  commands = self._ensure_migration_commands()
275
- return commands.current(verbose=verbose)
276
278
 
277
- def create_migration(self, message: str, file_type: str = "sql") -> None:
279
+ return await cast("AsyncMigrationCommands", commands).current(verbose=verbose)
280
+
281
+ async def create_migration(self, message: str, file_type: str = "sql") -> None:
278
282
  """Create a new migration file.
279
283
 
280
284
  Args:
@@ -282,9 +286,10 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
282
286
  file_type: Type of migration file to create ('sql' or 'py'). Defaults to 'sql'.
283
287
  """
284
288
  commands = self._ensure_migration_commands()
285
- commands.revision(message, file_type)
286
289
 
287
- def init_migrations(self, directory: "Optional[str]" = None, package: bool = True) -> None:
290
+ await cast("AsyncMigrationCommands", commands).revision(message, file_type)
291
+
292
+ async def init_migrations(self, directory: "Optional[str]" = None, package: bool = True) -> None:
288
293
  """Initialize migration directory structure.
289
294
 
290
295
  Args:
@@ -297,7 +302,8 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
297
302
 
298
303
  commands = self._ensure_migration_commands()
299
304
  assert directory is not None
300
- commands.init(directory, package)
305
+
306
+ await cast("AsyncMigrationCommands", commands).init(directory, package)
301
307
 
302
308
 
303
309
  class NoPoolSyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
@@ -315,7 +321,9 @@ class NoPoolSyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
315
321
  migration_config: "Optional[Union[dict[str, Any], MigrationConfig]]" = None,
316
322
  statement_config: "Optional[StatementConfig]" = None,
317
323
  driver_features: "Optional[dict[str, Any]]" = None,
324
+ bind_key: "Optional[str]" = None,
318
325
  ) -> None:
326
+ self.bind_key = bind_key
319
327
  self.pool_instance = None
320
328
  self.connection_config = connection_config or {}
321
329
  self.migration_config: Union[dict[str, Any], MigrationConfig] = migration_config or {}
@@ -369,7 +377,9 @@ class NoPoolAsyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
369
377
  migration_config: "Optional[Union[dict[str, Any], MigrationConfig]]" = None,
370
378
  statement_config: "Optional[StatementConfig]" = None,
371
379
  driver_features: "Optional[dict[str, Any]]" = None,
380
+ bind_key: "Optional[str]" = None,
372
381
  ) -> None:
382
+ self.bind_key = bind_key
373
383
  self.pool_instance = None
374
384
  self.connection_config = connection_config or {}
375
385
  self.migration_config: Union[dict[str, Any], MigrationConfig] = migration_config or {}
@@ -424,7 +434,9 @@ class SyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
424
434
  migration_config: "Optional[Union[dict[str, Any], MigrationConfig]]" = None,
425
435
  statement_config: "Optional[StatementConfig]" = None,
426
436
  driver_features: "Optional[dict[str, Any]]" = None,
437
+ bind_key: "Optional[str]" = None,
427
438
  ) -> None:
439
+ self.bind_key = bind_key
428
440
  self.pool_instance = pool_instance
429
441
  self.pool_config = pool_config or {}
430
442
  self.migration_config: Union[dict[str, Any], MigrationConfig] = migration_config or {}
@@ -501,7 +513,9 @@ class AsyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
501
513
  migration_config: "Optional[Union[dict[str, Any], MigrationConfig]]" = None,
502
514
  statement_config: "Optional[StatementConfig]" = None,
503
515
  driver_features: "Optional[dict[str, Any]]" = None,
516
+ bind_key: "Optional[str]" = None,
504
517
  ) -> None:
518
+ self.bind_key = bind_key
505
519
  self.pool_instance = pool_instance
506
520
  self.pool_config = pool_config or {}
507
521
  self.migration_config: Union[dict[str, Any], MigrationConfig] = migration_config or {}
sqlspec/core/__init__.py CHANGED
@@ -90,7 +90,7 @@ Example Usage:
90
90
  """
91
91
 
92
92
  from sqlspec.core import filters
93
- from sqlspec.core.cache import CacheConfig, CacheStats, UnifiedCache, get_statement_cache
93
+ from sqlspec.core.cache import CacheConfig, CacheStats, MultiLevelCache, UnifiedCache, get_cache
94
94
  from sqlspec.core.compiler import OperationType, SQLProcessor
95
95
  from sqlspec.core.filters import StatementFilter
96
96
  from sqlspec.core.hashing import (
@@ -115,6 +115,7 @@ __all__ = (
115
115
  "ArrowResult",
116
116
  "CacheConfig",
117
117
  "CacheStats",
118
+ "MultiLevelCache",
118
119
  "OperationType",
119
120
  "ParameterConverter",
120
121
  "ParameterProcessor",
@@ -129,7 +130,7 @@ __all__ = (
129
130
  "TypedParameter",
130
131
  "UnifiedCache",
131
132
  "filters",
132
- "get_statement_cache",
133
+ "get_cache",
133
134
  "hash_expression",
134
135
  "hash_expression_node",
135
136
  "hash_optimized_expression",