sqlspec 0.17.1__py3-none-any.whl → 0.18.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 (75) hide show
  1. sqlspec/__init__.py +1 -1
  2. sqlspec/_sql.py +54 -159
  3. sqlspec/adapters/adbc/config.py +24 -30
  4. sqlspec/adapters/adbc/driver.py +42 -61
  5. sqlspec/adapters/aiosqlite/config.py +5 -10
  6. sqlspec/adapters/aiosqlite/driver.py +9 -25
  7. sqlspec/adapters/aiosqlite/pool.py +43 -35
  8. sqlspec/adapters/asyncmy/config.py +10 -7
  9. sqlspec/adapters/asyncmy/driver.py +18 -39
  10. sqlspec/adapters/asyncpg/config.py +4 -0
  11. sqlspec/adapters/asyncpg/driver.py +32 -79
  12. sqlspec/adapters/bigquery/config.py +12 -65
  13. sqlspec/adapters/bigquery/driver.py +39 -133
  14. sqlspec/adapters/duckdb/config.py +11 -15
  15. sqlspec/adapters/duckdb/driver.py +61 -85
  16. sqlspec/adapters/duckdb/pool.py +2 -5
  17. sqlspec/adapters/oracledb/_types.py +8 -1
  18. sqlspec/adapters/oracledb/config.py +55 -38
  19. sqlspec/adapters/oracledb/driver.py +35 -92
  20. sqlspec/adapters/oracledb/migrations.py +257 -0
  21. sqlspec/adapters/psqlpy/config.py +13 -9
  22. sqlspec/adapters/psqlpy/driver.py +28 -103
  23. sqlspec/adapters/psycopg/config.py +9 -5
  24. sqlspec/adapters/psycopg/driver.py +107 -175
  25. sqlspec/adapters/sqlite/config.py +7 -5
  26. sqlspec/adapters/sqlite/driver.py +37 -73
  27. sqlspec/adapters/sqlite/pool.py +3 -12
  28. sqlspec/base.py +1 -8
  29. sqlspec/builder/__init__.py +1 -1
  30. sqlspec/builder/_base.py +34 -20
  31. sqlspec/builder/_ddl.py +407 -183
  32. sqlspec/builder/_insert.py +1 -1
  33. sqlspec/builder/mixins/_insert_operations.py +26 -6
  34. sqlspec/builder/mixins/_merge_operations.py +1 -1
  35. sqlspec/builder/mixins/_select_operations.py +1 -5
  36. sqlspec/config.py +32 -13
  37. sqlspec/core/__init__.py +89 -14
  38. sqlspec/core/cache.py +57 -104
  39. sqlspec/core/compiler.py +57 -112
  40. sqlspec/core/filters.py +1 -21
  41. sqlspec/core/hashing.py +13 -47
  42. sqlspec/core/parameters.py +272 -261
  43. sqlspec/core/result.py +12 -27
  44. sqlspec/core/splitter.py +17 -21
  45. sqlspec/core/statement.py +150 -159
  46. sqlspec/driver/_async.py +2 -15
  47. sqlspec/driver/_common.py +16 -95
  48. sqlspec/driver/_sync.py +2 -15
  49. sqlspec/driver/mixins/_result_tools.py +8 -29
  50. sqlspec/driver/mixins/_sql_translator.py +6 -8
  51. sqlspec/exceptions.py +1 -2
  52. sqlspec/loader.py +43 -115
  53. sqlspec/migrations/__init__.py +1 -1
  54. sqlspec/migrations/base.py +34 -45
  55. sqlspec/migrations/commands.py +34 -15
  56. sqlspec/migrations/loaders.py +1 -1
  57. sqlspec/migrations/runner.py +104 -19
  58. sqlspec/migrations/tracker.py +49 -2
  59. sqlspec/protocols.py +3 -6
  60. sqlspec/storage/__init__.py +4 -4
  61. sqlspec/storage/backends/fsspec.py +5 -6
  62. sqlspec/storage/backends/obstore.py +7 -8
  63. sqlspec/storage/registry.py +3 -3
  64. sqlspec/utils/__init__.py +2 -2
  65. sqlspec/utils/logging.py +6 -10
  66. sqlspec/utils/sync_tools.py +27 -4
  67. sqlspec/utils/text.py +6 -1
  68. {sqlspec-0.17.1.dist-info → sqlspec-0.18.0.dist-info}/METADATA +1 -1
  69. sqlspec-0.18.0.dist-info/RECORD +138 -0
  70. sqlspec/builder/_ddl_utils.py +0 -103
  71. sqlspec-0.17.1.dist-info/RECORD +0 -138
  72. {sqlspec-0.17.1.dist-info → sqlspec-0.18.0.dist-info}/WHEEL +0 -0
  73. {sqlspec-0.17.1.dist-info → sqlspec-0.18.0.dist-info}/entry_points.txt +0 -0
  74. {sqlspec-0.17.1.dist-info → sqlspec-0.18.0.dist-info}/licenses/LICENSE +0 -0
  75. {sqlspec-0.17.1.dist-info → sqlspec-0.18.0.dist-info}/licenses/NOTICE +0 -0
@@ -7,15 +7,18 @@ import os
7
7
  from typing import TYPE_CHECKING, Any, Optional
8
8
 
9
9
  from sqlspec.migrations.base import BaseMigrationTracker
10
+ from sqlspec.utils.logging import get_logger
10
11
 
11
12
  if TYPE_CHECKING:
12
13
  from sqlspec.driver import AsyncDriverAdapterBase, SyncDriverAdapterBase
13
14
 
14
15
  __all__ = ("AsyncMigrationTracker", "SyncMigrationTracker")
15
16
 
17
+ logger = get_logger("migrations.tracker")
18
+
16
19
 
17
20
  class SyncMigrationTracker(BaseMigrationTracker["SyncDriverAdapterBase"]):
18
- """Tracks applied migrations in the database."""
21
+ """Synchronous migration version tracker."""
19
22
 
20
23
  def ensure_tracking_table(self, driver: "SyncDriverAdapterBase") -> None:
21
24
  """Create the migration tracking table if it doesn't exist.
@@ -24,6 +27,7 @@ class SyncMigrationTracker(BaseMigrationTracker["SyncDriverAdapterBase"]):
24
27
  driver: The database driver to use.
25
28
  """
26
29
  driver.execute(self._get_create_table_sql())
30
+ self._safe_commit(driver)
27
31
 
28
32
  def get_current_version(self, driver: "SyncDriverAdapterBase") -> Optional[str]:
29
33
  """Get the latest applied migration version.
@@ -66,6 +70,7 @@ class SyncMigrationTracker(BaseMigrationTracker["SyncDriverAdapterBase"]):
66
70
  version, description, execution_time_ms, checksum, os.environ.get("USER", "unknown")
67
71
  )
68
72
  )
73
+ self._safe_commit(driver)
69
74
 
70
75
  def remove_migration(self, driver: "SyncDriverAdapterBase", version: str) -> None:
71
76
  """Remove a migration record (used during downgrade).
@@ -75,10 +80,30 @@ class SyncMigrationTracker(BaseMigrationTracker["SyncDriverAdapterBase"]):
75
80
  version: Version number to remove.
76
81
  """
77
82
  driver.execute(self._get_remove_migration_sql(version))
83
+ self._safe_commit(driver)
84
+
85
+ def _safe_commit(self, driver: "SyncDriverAdapterBase") -> None:
86
+ """Safely commit a transaction only if autocommit is disabled.
87
+
88
+ Args:
89
+ driver: The database driver to use.
90
+ """
91
+ try:
92
+ connection = getattr(driver, "connection", None)
93
+ if connection and hasattr(connection, "autocommit") and getattr(connection, "autocommit", False):
94
+ return
95
+
96
+ driver_features = getattr(driver, "driver_features", {})
97
+ if driver_features and driver_features.get("autocommit", False):
98
+ return
99
+
100
+ driver.commit()
101
+ except Exception:
102
+ logger.debug("Failed to commit transaction, likely due to autocommit being enabled")
78
103
 
79
104
 
80
105
  class AsyncMigrationTracker(BaseMigrationTracker["AsyncDriverAdapterBase"]):
81
- """Tracks applied migrations in the database."""
106
+ """Asynchronous migration version tracker."""
82
107
 
83
108
  async def ensure_tracking_table(self, driver: "AsyncDriverAdapterBase") -> None:
84
109
  """Create the migration tracking table if it doesn't exist.
@@ -87,6 +112,7 @@ class AsyncMigrationTracker(BaseMigrationTracker["AsyncDriverAdapterBase"]):
87
112
  driver: The database driver to use.
88
113
  """
89
114
  await driver.execute(self._get_create_table_sql())
115
+ await self._safe_commit_async(driver)
90
116
 
91
117
  async def get_current_version(self, driver: "AsyncDriverAdapterBase") -> Optional[str]:
92
118
  """Get the latest applied migration version.
@@ -129,6 +155,7 @@ class AsyncMigrationTracker(BaseMigrationTracker["AsyncDriverAdapterBase"]):
129
155
  version, description, execution_time_ms, checksum, os.environ.get("USER", "unknown")
130
156
  )
131
157
  )
158
+ await self._safe_commit_async(driver)
132
159
 
133
160
  async def remove_migration(self, driver: "AsyncDriverAdapterBase", version: str) -> None:
134
161
  """Remove a migration record (used during downgrade).
@@ -138,3 +165,23 @@ class AsyncMigrationTracker(BaseMigrationTracker["AsyncDriverAdapterBase"]):
138
165
  version: Version number to remove.
139
166
  """
140
167
  await driver.execute(self._get_remove_migration_sql(version))
168
+ await self._safe_commit_async(driver)
169
+
170
+ async def _safe_commit_async(self, driver: "AsyncDriverAdapterBase") -> None:
171
+ """Safely commit a transaction only if autocommit is disabled.
172
+
173
+ Args:
174
+ driver: The database driver to use.
175
+ """
176
+ try:
177
+ connection = getattr(driver, "connection", None)
178
+ if connection and hasattr(connection, "autocommit") and getattr(connection, "autocommit", False):
179
+ return
180
+
181
+ driver_features = getattr(driver, "driver_features", {})
182
+ if driver_features and driver_features.get("autocommit", False):
183
+ return
184
+
185
+ await driver.commit()
186
+ except Exception:
187
+ logger.debug("Failed to commit transaction, likely due to autocommit being enabled")
sqlspec/protocols.py CHANGED
@@ -1,7 +1,7 @@
1
- """Runtime-checkable protocols for SQLSpec to replace duck typing.
1
+ """Runtime-checkable protocols for type safety and runtime checks.
2
2
 
3
3
  This module provides protocols that can be used for static type checking
4
- and runtime isinstance() checks, replacing defensive hasattr() patterns.
4
+ and runtime isinstance() checks.
5
5
  """
6
6
 
7
7
  from typing import TYPE_CHECKING, Any, ClassVar, Optional, Protocol, Union, runtime_checkable
@@ -192,10 +192,7 @@ class ObjectStoreItemProtocol(Protocol):
192
192
 
193
193
  @runtime_checkable
194
194
  class ObjectStoreProtocol(Protocol):
195
- """Protocol for object storage operations.
196
-
197
- Defines the interface for storage backends with both sync and async operations.
198
- """
195
+ """Protocol for object storage operations."""
199
196
 
200
197
  capabilities: ClassVar["StorageCapabilities"]
201
198
 
@@ -1,10 +1,10 @@
1
1
  """Storage abstraction layer for SQLSpec.
2
2
 
3
- Provides a flexible storage system with:
3
+ Provides a storage system with:
4
4
  - Multiple backend support (local, fsspec, obstore)
5
- - Lazy loading and configuration-based registration
6
- - URI scheme-based automatic backend resolution
7
- - Key-based named storage configurations
5
+ - Configuration-based registration
6
+ - URI scheme-based backend resolution
7
+ - Named storage configurations
8
8
  - Capability-based backend selection
9
9
  """
10
10
 
@@ -32,7 +32,7 @@ class _ArrowStreamer:
32
32
  return self
33
33
 
34
34
  async def _initialize(self) -> None:
35
- """Initialize the paths iterator."""
35
+ """Initialize paths iterator."""
36
36
  if self.paths_iterator is None:
37
37
  paths = await async_(self.backend.glob)(self.pattern, **self.kwargs)
38
38
  self.paths_iterator = iter(paths)
@@ -59,9 +59,8 @@ class _ArrowStreamer:
59
59
  class FSSpecBackend(ObjectStoreBase):
60
60
  """Storage backend using fsspec.
61
61
 
62
- Implements the ObjectStoreProtocol using fsspec,
63
- providing support for various protocols including HTTP, HTTPS, FTP,
64
- and cloud storage services.
62
+ Implements the ObjectStoreProtocol using fsspec for various protocols
63
+ including HTTP, HTTPS, FTP, and cloud storage services.
65
64
  """
66
65
 
67
66
  _default_capabilities: ClassVar[StorageCapabilities] = StorageCapabilities(
@@ -116,7 +115,7 @@ class FSSpecBackend(ObjectStoreBase):
116
115
  return path_str
117
116
 
118
117
  def _detect_capabilities(self) -> StorageCapabilities:
119
- """Detect capabilities based on underlying filesystem protocol."""
118
+ """Detect capabilities based on filesystem protocol."""
120
119
  protocol = self.protocol.lower()
121
120
 
122
121
  if protocol in {"s3", "s3a", "s3n"}:
@@ -138,7 +137,7 @@ class FSSpecBackend(ObjectStoreBase):
138
137
 
139
138
  @property
140
139
  def capabilities(self) -> StorageCapabilities:
141
- """Return instance-specific capabilities based on detected protocol."""
140
+ """Return capabilities based on detected protocol."""
142
141
  return getattr(self, "_instance_capabilities", self.__class__._default_capabilities)
143
142
 
144
143
  @classmethod
@@ -1,8 +1,7 @@
1
1
  """Object storage backend using obstore.
2
2
 
3
- Implements the ObjectStoreProtocol using obstore,
4
- providing native support for S3, GCS, Azure, and local file storage
5
- with Arrow support.
3
+ Implements the ObjectStoreProtocol using obstore for S3, GCS, Azure,
4
+ and local file storage with Arrow support.
6
5
  """
7
6
 
8
7
  from __future__ import annotations
@@ -56,11 +55,11 @@ DEFAULT_OPTIONS: Final[dict[str, Any]] = {"connect_timeout": "30s", "request_tim
56
55
  class ObStoreBackend(ObjectStoreBase, HasStorageCapabilities):
57
56
  """Object storage backend using obstore.
58
57
 
59
- Uses obstore's Rust-based implementation for storage operations,
60
- providing native support for AWS S3, Google Cloud Storage, Azure Blob Storage,
58
+ Uses obstore's Rust-based implementation for storage operations.
59
+ Supports AWS S3, Google Cloud Storage, Azure Blob Storage,
61
60
  local filesystem, and HTTP endpoints.
62
61
 
63
- Includes native Arrow support.
62
+ Includes Arrow support.
64
63
  """
65
64
 
66
65
  capabilities: ClassVar[StorageCapabilities] = StorageCapabilities(
@@ -203,7 +202,7 @@ class ObStoreBackend(ObjectStoreBase, HasStorageCapabilities):
203
202
  raise StorageOperationFailedError(msg) from exc
204
203
 
205
204
  def glob(self, pattern: str, **kwargs: Any) -> list[str]:
206
- """Find objects matching pattern using obstore.
205
+ """Find objects matching pattern.
207
206
 
208
207
  Lists all objects and filters them client-side using the pattern.
209
208
  """
@@ -330,7 +329,7 @@ class ObStoreBackend(ObjectStoreBase, HasStorageCapabilities):
330
329
  raise StorageOperationFailedError(msg) from exc
331
330
 
332
331
  def stream_arrow(self, pattern: str, **kwargs: Any) -> Iterator[ArrowRecordBatch]:
333
- """Stream Arrow record batches using obstore.
332
+ """Stream Arrow record batches.
334
333
 
335
334
  Yields:
336
335
  Iterator of Arrow record batches from matching objects.
@@ -1,8 +1,8 @@
1
- """Unified Storage Registry for ObjectStore backends.
1
+ """Storage Registry for ObjectStore backends.
2
2
 
3
- Provides a flexible, lazy-loading storage registry that supports URI-first access
3
+ Provides a storage registry that supports URI-first access
4
4
  pattern with automatic backend detection, ObStore preferred with FSSpec fallback,
5
- intelligent scheme-based routing, and named aliases for common configurations.
5
+ scheme-based routing, and named aliases for common configurations.
6
6
  """
7
7
 
8
8
  import logging
sqlspec/utils/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
- from sqlspec.utils import deprecation, fixtures, module_loader, singleton, sync_tools, text, type_guards
1
+ from sqlspec.utils import deprecation, fixtures, logging, module_loader, singleton, sync_tools, text, type_guards
2
2
 
3
- __all__ = ("deprecation", "fixtures", "module_loader", "singleton", "sync_tools", "text", "type_guards")
3
+ __all__ = ("deprecation", "fixtures", "logging", "module_loader", "singleton", "sync_tools", "text", "type_guards")
sqlspec/utils/logging.py CHANGED
@@ -5,23 +5,19 @@ Users should configure their own logging handlers and levels as needed.
5
5
  SQLSpec provides StructuredFormatter for JSON-formatted logs if desired.
6
6
  """
7
7
 
8
- from __future__ import annotations
9
-
10
8
  import logging
11
9
  from contextvars import ContextVar
12
- from typing import TYPE_CHECKING, Any
10
+ from logging import LogRecord
11
+ from typing import Any, Optional
13
12
 
14
13
  from sqlspec._serialization import encode_json
15
14
 
16
- if TYPE_CHECKING:
17
- from logging import LogRecord
18
-
19
15
  __all__ = ("StructuredFormatter", "correlation_id_var", "get_correlation_id", "get_logger", "set_correlation_id")
20
16
 
21
- correlation_id_var: ContextVar[str | None] = ContextVar("correlation_id", default=None)
17
+ correlation_id_var: "ContextVar[Optional[str]]" = ContextVar("correlation_id", default=None)
22
18
 
23
19
 
24
- def set_correlation_id(correlation_id: str | None) -> None:
20
+ def set_correlation_id(correlation_id: "Optional[str]") -> None:
25
21
  """Set the correlation ID for the current context.
26
22
 
27
23
  Args:
@@ -30,7 +26,7 @@ def set_correlation_id(correlation_id: str | None) -> None:
30
26
  correlation_id_var.set(correlation_id)
31
27
 
32
28
 
33
- def get_correlation_id() -> str | None:
29
+ def get_correlation_id() -> "Optional[str]":
34
30
  """Get the current correlation ID.
35
31
 
36
32
  Returns:
@@ -90,7 +86,7 @@ class CorrelationIDFilter(logging.Filter):
90
86
  return True
91
87
 
92
88
 
93
- def get_logger(name: str | None = None) -> logging.Logger:
89
+ def get_logger(name: "Optional[str]" = None) -> logging.Logger:
94
90
  """Get a logger instance with standardized configuration.
95
91
 
96
92
  Args:
@@ -1,3 +1,10 @@
1
+ """Utilities for async/sync interoperability in SQLSpec.
2
+
3
+ This module provides utilities for converting between async and sync functions,
4
+ managing concurrency limits, and handling context managers. Used primarily
5
+ for adapter implementations that need to support both sync and async patterns.
6
+ """
7
+
1
8
  import asyncio
2
9
  import functools
3
10
  import inspect
@@ -26,7 +33,15 @@ class CapacityLimiter:
26
33
  """Limits the number of concurrent operations using a semaphore."""
27
34
 
28
35
  def __init__(self, total_tokens: int) -> None:
29
- self._semaphore = asyncio.Semaphore(total_tokens)
36
+ self._total_tokens = total_tokens
37
+ self._semaphore_instance: Optional[asyncio.Semaphore] = None
38
+
39
+ @property
40
+ def _semaphore(self) -> asyncio.Semaphore:
41
+ """Lazy initialization of asyncio.Semaphore for Python 3.9 compatibility."""
42
+ if self._semaphore_instance is None:
43
+ self._semaphore_instance = asyncio.Semaphore(self._total_tokens)
44
+ return self._semaphore_instance
30
45
 
31
46
  async def acquire(self) -> None:
32
47
  await self._semaphore.acquire()
@@ -36,11 +51,12 @@ class CapacityLimiter:
36
51
 
37
52
  @property
38
53
  def total_tokens(self) -> int:
39
- return self._semaphore._value
54
+ return self._total_tokens
40
55
 
41
56
  @total_tokens.setter
42
57
  def total_tokens(self, value: int) -> None:
43
- self._semaphore = asyncio.Semaphore(value)
58
+ self._total_tokens = value
59
+ self._semaphore_instance = None
44
60
 
45
61
  async def __aenter__(self) -> None:
46
62
  await self.acquire()
@@ -76,7 +92,14 @@ def run_(async_function: "Callable[ParamSpecT, Coroutine[Any, Any, ReturnT]]") -
76
92
  loop = None
77
93
 
78
94
  if loop is not None:
79
- return asyncio.run(partial_f())
95
+ if loop.is_running():
96
+ import concurrent.futures
97
+
98
+ with concurrent.futures.ThreadPoolExecutor() as executor:
99
+ future = executor.submit(asyncio.run, partial_f())
100
+ return future.result()
101
+ else:
102
+ return asyncio.run(partial_f())
80
103
  if uvloop and sys.platform != "win32":
81
104
  uvloop.install() # pyright: ignore[reportUnknownMemberType]
82
105
  return asyncio.run(partial_f())
sqlspec/utils/text.py CHANGED
@@ -1,4 +1,9 @@
1
- """General utility functions."""
1
+ """Text processing utilities for SQLSpec.
2
+
3
+ Provides functions for string manipulation including case conversion,
4
+ slugification, and email validation. Used primarily for identifier
5
+ generation and data validation.
6
+ """
2
7
 
3
8
  import re
4
9
  import unicodedata
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlspec
3
- Version: 0.17.1
3
+ Version: 0.18.0
4
4
  Summary: SQL Experiments in Python
5
5
  Project-URL: Discord, https://discord.gg/litestar
6
6
  Project-URL: Issue, https://github.com/litestar-org/sqlspec/issues/
@@ -0,0 +1,138 @@
1
+ sqlspec/__init__.py,sha256=JkL9cp1h19tz1rCl-3WAep6kbZs8JLxNlb1SrQl8PWc,2114
2
+ sqlspec/__main__.py,sha256=lXBKZMOXA1uY735Rnsb-GS7aXy0nt22tYmd2X9FcxrY,253
3
+ sqlspec/__metadata__.py,sha256=IUw6MCTy1oeUJ1jAVYbuJLkOWbiAWorZ5W-E-SAD9N4,395
4
+ sqlspec/_serialization.py,sha256=6U5-smk2h2yl0i6am2prtOLJTdu4NJQdcLlSfSUMaUQ,2590
5
+ sqlspec/_sql.py,sha256=j9WljOgCme4jTfL6NegEWOhK-Rr3JEmhtbneh8ZN1bQ,45221
6
+ sqlspec/_typing.py,sha256=jv-7QHGLrJLfnP86bR-Xcmj3PDoddNZEKDz_vYRBiAU,22684
7
+ sqlspec/base.py,sha256=-5hxBpjEvbn30aXksbErkw3lH0Q3-u7h6D2JB9BSAmU,25429
8
+ sqlspec/cli.py,sha256=3ZxPwl4neNWyrAkM9J9ccC_gaFigDJbhuZfx15JVE7E,9903
9
+ sqlspec/config.py,sha256=QJMR46YC-6Kd4GUnqQm0s679Br4R-QEEruuKpJxHEec,15969
10
+ sqlspec/exceptions.py,sha256=zBnzQOfYAgqX04GoaC9Io6ardzinldkEuZ3YtR5vr9U,6071
11
+ sqlspec/loader.py,sha256=HDfMZDj7l9aLAxeZR2Rv-HC-dWah4CPkwZ6HKQ7yP-Y,23398
12
+ sqlspec/protocols.py,sha256=Of6uJyxvawExCEyR3u7jbxOckUcwG0HHOEXmfHyev40,13106
13
+ sqlspec/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ sqlspec/typing.py,sha256=yj8D8O-pkfUVZDfVHEgQaB95-5alwgQbp_sqNJOVhvQ,6301
15
+ sqlspec/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ sqlspec/adapters/adbc/__init__.py,sha256=CqBaEahvHbQ5NxmBJuuCtZ8v5wuaPgbqSSe9WUhglWY,336
17
+ sqlspec/adapters/adbc/_types.py,sha256=htTZ20qVo6Iod_ooUTLGd0xAL8AUYA4qeOexTaLQG3Q,351
18
+ sqlspec/adapters/adbc/config.py,sha256=gekx9tzOA5vpcMWqczX5B5xKMbXCEnyYWavrrYll7j0,13583
19
+ sqlspec/adapters/adbc/driver.py,sha256=E36PI499cMsi-CGeRNe21lkiIwZKNSHGusmxLxy6mIQ,18809
20
+ sqlspec/adapters/aiosqlite/__init__.py,sha256=rgooFeHm7IsnC9fOnRQwMvbJdgkTvhnNTYphayVz9q8,869
21
+ sqlspec/adapters/aiosqlite/_types.py,sha256=M8VqaW6iCigfExhdJM2yPAN09Ue2yBoBL59-QXGBObo,355
22
+ sqlspec/adapters/aiosqlite/config.py,sha256=MmCl_0Be89OijlcY1EUgA87A1NNtF1CHjl6p_R6Dfks,8112
23
+ sqlspec/adapters/aiosqlite/driver.py,sha256=pqrrRNmKKeEPX8871TzLwdehFB6-6ULwpM2Ke9Tsl-o,9458
24
+ sqlspec/adapters/aiosqlite/pool.py,sha256=cuzkXA2hMMk16aX28aNRaTmLDmqlepka9QhcWsdUA2E,17140
25
+ sqlspec/adapters/asyncmy/__init__.py,sha256=wBgak4MA3ySaGQHUxrnv3HdSVQKKRWf1_DmENL0LkWs,531
26
+ sqlspec/adapters/asyncmy/_types.py,sha256=WbwREzJkLYmqd4c7A7cu04WaD5g7-n35ZETHZvbP1Z8,250
27
+ sqlspec/adapters/asyncmy/config.py,sha256=DHk-MTkBcGPPmYI4RMJbUWWKbcu1ZaoG_8LS0aZR0P8,6603
28
+ sqlspec/adapters/asyncmy/driver.py,sha256=DitgufSL3N4LlDOq_UB741f4czPPPTJrusLbuiSjagY,9911
29
+ sqlspec/adapters/asyncpg/__init__.py,sha256=h3lg3pLBLrS9ABBt5yKFKhGL69RpOlASYSqVCuAuURY,567
30
+ sqlspec/adapters/asyncpg/_types.py,sha256=p65WrqfUl2cx5Md759_aV8m_gHP-PyCzNk48bLhDQkc,425
31
+ sqlspec/adapters/asyncpg/config.py,sha256=WrP-PZeWbumpKb8VrJYD-8hpBkjrNG1PQ5kfR2vFWo4,8867
32
+ sqlspec/adapters/asyncpg/driver.py,sha256=ZEuCeyrpaIQme0cF-hupGlfxbkN9ReZBjflpgbEJEw8,11073
33
+ sqlspec/adapters/bigquery/__init__.py,sha256=1nzkWubO4ZObuK27QoeGfS05ed5v02NU4GaXrvqjlw0,504
34
+ sqlspec/adapters/bigquery/_types.py,sha256=gECmbiSmZmnR-xJpmznhnva4SbhhdcYQ09jBdqMAmOs,255
35
+ sqlspec/adapters/bigquery/config.py,sha256=Dp0LKg9p88n4C4WQMaf9_A7YicIJT9DgcCXci46NTFk,9434
36
+ sqlspec/adapters/bigquery/driver.py,sha256=gAQWd8R3NaqYzbPkNr59kxKVKW8Yz4KmU7BjUJXesoo,17745
37
+ sqlspec/adapters/duckdb/__init__.py,sha256=c5GCYxhTFhvB8fUTt_d-dipaQfM8X5kv4GsU47SwJ6E,693
38
+ sqlspec/adapters/duckdb/_types.py,sha256=4p5nuD1yNs0fmQ5sGxKFx2ru6jUCPrpsYgqfh-uZHM8,270
39
+ sqlspec/adapters/duckdb/config.py,sha256=7CWXpKWX1NrzO1sORVFfD3TzdVxj62MbujnsBBCGSHQ,10037
40
+ sqlspec/adapters/duckdb/driver.py,sha256=TiQ1HEWVJUwxENZFca62slYMqvFzVa11P3nhf8TggTA,12491
41
+ sqlspec/adapters/duckdb/pool.py,sha256=2P4iAhJQ070wA_0O_ZXNfOCiXFxaW7zeyoL05A7izL4,8413
42
+ sqlspec/adapters/oracledb/__init__.py,sha256=AUsZ8m9tDgNwxv9m4LtkIs9Ib6hOtBrGNm-Ee4HWNq0,843
43
+ sqlspec/adapters/oracledb/_types.py,sha256=7Oe0DmA1ixptQjPMioQF7r2i451zzN2BMut2jTi2c3U,808
44
+ sqlspec/adapters/oracledb/config.py,sha256=xdVObosNsGVhtuiWRfMQ9_78pO25vCOUIy_ktM8sYWc,12037
45
+ sqlspec/adapters/oracledb/driver.py,sha256=XwkQGEWksXmS5wT13-vDuwqN5D203Z7C1KzuWWOr55g,19275
46
+ sqlspec/adapters/oracledb/migrations.py,sha256=FwjkMBbzEQRkvZdfvpPUyPiWHCP6A_IVg6_6RIYSXYA,9136
47
+ sqlspec/adapters/psqlpy/__init__.py,sha256=ABve2Oj-G-fxMO8WRJ0XzxEw2cs5H3INDnmUI99l8gc,526
48
+ sqlspec/adapters/psqlpy/_types.py,sha256=tG4jwQtBB6mCX5KU5x3hAhxsQUQlQEzbCsYhU3IouVc,269
49
+ sqlspec/adapters/psqlpy/config.py,sha256=ZDZKscjDViyID78SNfOeY9IZZFYQD__hJoYLFBm4TCo,7908
50
+ sqlspec/adapters/psqlpy/driver.py,sha256=Rxpoezw6mrnqlhEB0DrYUHQK7ed-wLtgXYLV2gtJlwI,16146
51
+ sqlspec/adapters/psycopg/__init__.py,sha256=swmTz8xlj6LvB-i78tBSE_T-sez2e6lFJW2cMzNJEVE,862
52
+ sqlspec/adapters/psycopg/_types.py,sha256=UJBKDWgARoSR6UxSy8zcIP7HSHTpXU5moJTsjDj0M4M,563
53
+ sqlspec/adapters/psycopg/config.py,sha256=PP6iwIKvINzOXZE4b99auCgR6eEfzSX-sFyHcBMb-xg,16558
54
+ sqlspec/adapters/psycopg/driver.py,sha256=6Xp3MmMc7xZBpL8mdVlR5FMInXsREkob588t_oNHoVE,26762
55
+ sqlspec/adapters/sqlite/__init__.py,sha256=hGZX0D6vHJMSah60_hgWHoLmcqKGm1lYcz2r02wc0p0,574
56
+ sqlspec/adapters/sqlite/_types.py,sha256=4Nqolhk8s4mwLw13BwUjuyhAbM9BsKwJCvcmjMWkhaY,246
57
+ sqlspec/adapters/sqlite/config.py,sha256=zXKipKuTPjFSUgdc5tiHAZF5hW33jvrrElNJAQhpOQM,5069
58
+ sqlspec/adapters/sqlite/driver.py,sha256=52WzO8cGIERBv6fWYQYp6Myti9wYHyBzuLN8dJxsNZY,9409
59
+ sqlspec/adapters/sqlite/pool.py,sha256=bKIrf3hgach6bMyFQORCdqnpN-sTfMagB3l61uPCGJI,4435
60
+ sqlspec/builder/__init__.py,sha256=o328O3dNRj4vGXmOclIxDLzmiwkUCE_Aqmqv-LT5lWY,1665
61
+ sqlspec/builder/_base.py,sha256=SkyDJYZ7QCBi4CHZQ_0e1SvA05-Hhfbvi_qS7BwjcVA,18022
62
+ sqlspec/builder/_column.py,sha256=GfTMFPzJIhwDVKefMbyom-HoEj-KSKB92-XoZfchnEo,13289
63
+ sqlspec/builder/_ddl.py,sha256=AyL0d1BnHkESMoZQhdFQTgGEVYRiRt-cgDiX4IKE5Vg,56533
64
+ sqlspec/builder/_delete.py,sha256=xWA5nQB3UB8kpEGXN2k5ynt4cGZ7blkNoURpI0bKoeg,2264
65
+ sqlspec/builder/_expression_wrappers.py,sha256=HTl8qAFD4sZNXLD2akkJWGCPse2HWS237mTGE4Cx_7I,1244
66
+ sqlspec/builder/_insert.py,sha256=kqjjIfGcy49xDTTOMmb4GBvWsJqT1GOr_1Y0syAIsok,16863
67
+ sqlspec/builder/_merge.py,sha256=95PLQSKA3zjk0wTZG3m817fTZpsS95PrS2qF34iLAP8,2004
68
+ sqlspec/builder/_parsing_utils.py,sha256=RH8OFBFAetalEgHW5JLcEyyCdW_awVdy07MjboOkqL4,8383
69
+ sqlspec/builder/_select.py,sha256=m5sfyuAssjlNimLLNBAeFooVIfM2FgKN1boPfdsOkaA,5785
70
+ sqlspec/builder/_update.py,sha256=QieiguEq9T_UECv10f1xwQJp58gc3w246cvtCDpPwuw,6020
71
+ sqlspec/builder/mixins/__init__.py,sha256=YXhAzKmQbQtne5j26SKWY8PUxwosl0RhlhLoahAdkj0,1885
72
+ sqlspec/builder/mixins/_cte_and_set_ops.py,sha256=p5O9m_jvpaWxv1XP9Ys2DRI-qOTq30rr2EwYjAbIT8o,9088
73
+ sqlspec/builder/mixins/_delete_operations.py,sha256=l0liajnoAfRgtWtyStuAIfxreEFRkNO4DtBwyGqAfic,1198
74
+ sqlspec/builder/mixins/_insert_operations.py,sha256=ECFuX52fNYYxWt11e1n8jHx9wu5_RJSnmm9Dl_aXnIY,10326
75
+ sqlspec/builder/mixins/_join_operations.py,sha256=8o_aApK5cmJbNCNfWa4bs5fR2zgQUjon5p-oyiW41Qw,11440
76
+ sqlspec/builder/mixins/_merge_operations.py,sha256=KnvXxHKEJu3ofuQsLJlPf7H4mdkH4mKwGHoXtwzdK1o,24191
77
+ sqlspec/builder/mixins/_order_limit_operations.py,sha256=KrTXE0HmKCMn4AkNFyMhEZrmJ2Dl-o5kSiCjk2jNIKM,5499
78
+ sqlspec/builder/mixins/_pivot_operations.py,sha256=j5vdzXuEqB1Jn3Ie_QjVwSH2_OEi65oZ64bQJHd3jXo,6108
79
+ sqlspec/builder/mixins/_select_operations.py,sha256=7CwKu5pt5Nu4tdFIXciQOnd6IcbiRVO8YcOFWHePafg,35239
80
+ sqlspec/builder/mixins/_update_operations.py,sha256=rcmnmSSwHSujqe0gd-dKsWHLX9nPMS1we1Y3_h4S7G4,8654
81
+ sqlspec/builder/mixins/_where_clause.py,sha256=1iz7Y2x_ooG2bOCu2zX0v5_bkGFpAckVQKvnyrR1JNQ,36373
82
+ sqlspec/core/__init__.py,sha256=4pD6ymg_sZxh9QyAmsk3oNyvUWPoQj9qktg0uNJVp6k,5264
83
+ sqlspec/core/cache.py,sha256=835tHhe3fan9_h_Y9CJ-4aAl8K-0cNMwfQzcxMzjlqQ,24837
84
+ sqlspec/core/compiler.py,sha256=CdD5WqkUTUspetAN009mXF6aYmHCa1NdG6HbHAhjUMY,12066
85
+ sqlspec/core/filters.py,sha256=JQRFw7ND68tWvWQpLIZbDNUGk3mdcw9Yg-ldzLcfVqQ,30475
86
+ sqlspec/core/hashing.py,sha256=s8aY6xY0fOwYNIWYgUqmfkALt3BBK1s5Eq30fcnscL8,8529
87
+ sqlspec/core/parameters.py,sha256=pOSjWQqmuSgi4-eS3SMIfTcgXLVlM9Qd21G-vfVDymY,49083
88
+ sqlspec/core/result.py,sha256=yjc7mbntsrx7atrxb8CAdrvtUNLmSuCCM0N4J_zpzQA,20490
89
+ sqlspec/core/splitter.py,sha256=Qb4cyhs8ll3Wm9z11-WWsvpkUYnyEcmBz2KuYMG2evI,27914
90
+ sqlspec/core/statement.py,sha256=Ydk_OImRpmbu5EnvM0zgnOWw-H7tCWhoeJHlLZQBHbk,25906
91
+ sqlspec/driver/__init__.py,sha256=QVpDRQGd1GreIP199en6qDbq-cZJcEF5go68DINagUk,569
92
+ sqlspec/driver/_async.py,sha256=aS5AwY5IYqnVT8ldDLDwz2AMDN94CI9hfsOz-1k-Nus,18992
93
+ sqlspec/driver/_common.py,sha256=6vm4MY_CJW3Q8_roIG9hwK18tIMT_zIESmUoUyRSreg,23576
94
+ sqlspec/driver/_sync.py,sha256=wCBV9QfAH8BPjrrVCQc2eM90ai5-FYbKDd81L5sZMS0,18767
95
+ sqlspec/driver/mixins/__init__.py,sha256=gN4pQyJXxNy0xi91dcMJGA7DQ7TbjGjQI24SSpZc6Go,248
96
+ sqlspec/driver/mixins/_result_tools.py,sha256=4dLU-2uL6qCS-s7cve7DmHRZXKGPqdpWtl9OKMOgbR4,6599
97
+ sqlspec/driver/mixins/_sql_translator.py,sha256=wRj7neNbMFvzNfy7v0_acBAoZusKHh25UW2WsD_hSlQ,3005
98
+ sqlspec/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
99
+ sqlspec/extensions/aiosql/__init__.py,sha256=-9cefc9pYPf9vCgALoB-y1DtmcgRjKe2azfl6RIarAA,414
100
+ sqlspec/extensions/aiosql/adapter.py,sha256=CXkNZaZq86ZhfYFGx4IFbkHmbIFQKMd9CS6Q2jkMCok,16009
101
+ sqlspec/extensions/litestar/__init__.py,sha256=tOmQ7RHSWOot7p30gk0efxxuP0OCq1opyyZqNmQY7FE,320
102
+ sqlspec/extensions/litestar/_utils.py,sha256=o-FuUj1_WkDrLxQxiP6hXDak66XfyRP3QLyEVKrIRjI,1954
103
+ sqlspec/extensions/litestar/cli.py,sha256=X4DlAx3Ry-ccOjAQSxe8SMtyJKCFJVLTbENPU_efKuU,1356
104
+ sqlspec/extensions/litestar/config.py,sha256=3UI_vhtbupCLsf1nhUgUpRlCoUS5c0GsAjWvegT0c3c,4462
105
+ sqlspec/extensions/litestar/handlers.py,sha256=3LreU8rZvuHaJnKlN09ttu4wSorWJedsuKgeLT-cOEc,9993
106
+ sqlspec/extensions/litestar/plugin.py,sha256=I0aRnL4oZPUYk7pYhZSL3yikl7ViM0kr33kVmH4W-MU,5637
107
+ sqlspec/extensions/litestar/providers.py,sha256=5LRb5JvRV_XZdNOKkdaIy3j5x-dFCcAi1ea1pgwuapI,18882
108
+ sqlspec/migrations/__init__.py,sha256=RiDi_HkUIgXtu_33QnRdvYNqcCn-euHUiWwTiPr5IGc,1055
109
+ sqlspec/migrations/base.py,sha256=vIzQzUtQrNKDec6XUeRHcCBuWU1KNtRCFpOvVxsp3sQ,13093
110
+ sqlspec/migrations/commands.py,sha256=-De-1RnqjI-BwgOuFvULkJYZccPtmxPPAQTCLlU2TvM,19122
111
+ sqlspec/migrations/loaders.py,sha256=WSP3du5tLy9o5SsfvCCU9vhOiOA3ds7L_VzakrSfnmA,12932
112
+ sqlspec/migrations/runner.py,sha256=y6fyZi02n8MseKR8XFWXUEOOYQNG_w_DikHVxH9p20M,10730
113
+ sqlspec/migrations/tracker.py,sha256=hfrZGz8M70SfFniw4aXVtHNg4p8EPFm67vthjfUMUys,6843
114
+ sqlspec/migrations/utils.py,sha256=gWnCOdr8pwfkgG-FSUJgRz4q9TlCgOXY_B7n59NrgVA,3746
115
+ sqlspec/storage/__init__.py,sha256=xWSsq5QXrY7wCsjQYPldfdlm8UEJ-kojU-tWsoldSy0,645
116
+ sqlspec/storage/capabilities.py,sha256=vyousxls9jISsykgoybpNHlGWN6Hq_pKcsZ5DmKGWvU,3045
117
+ sqlspec/storage/registry.py,sha256=-H2ttz41M-DNfkEwANS704BDs1rtyii69G7iqsLGRG4,9424
118
+ sqlspec/storage/backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
119
+ sqlspec/storage/backends/base.py,sha256=KS2JRZILoH_R_xsfKtYkqQ5a1r5OOBDSE5KbibTmhGY,5730
120
+ sqlspec/storage/backends/fsspec.py,sha256=8AX8ULwlApMd6WtHDVJBomdvk5UjPtfMf78TJ86gTC8,15994
121
+ sqlspec/storage/backends/obstore.py,sha256=CXad0ug_b3snVNx50SzvvFsDXpkK4LV3jROIrwf6dhg,19783
122
+ sqlspec/utils/__init__.py,sha256=4Yd2HnY-DJ6wf4jBrNTM3B41KlCcaFefP7bnux7Q17g,231
123
+ sqlspec/utils/correlation.py,sha256=2jvkAY3nkU3UxNU_9pbBR6cz3A1Q1cGG9IaWSSOIb1Q,4195
124
+ sqlspec/utils/deprecation.py,sha256=L5ylPlkrWahXZ3q2Yta2ReFh4pA8rZapLNw9u_mOOEE,3794
125
+ sqlspec/utils/fixtures.py,sha256=Qm2uNMaL_6l6tlij-Pm3tLwD906iFK_OXhwZqOx3WgY,1807
126
+ sqlspec/utils/logging.py,sha256=zAM7rHJ-KsmAj1yjvU9QFoiwf4Q2hKTere2J62FlllI,3664
127
+ sqlspec/utils/module_loader.py,sha256=m5PSN9NwOLd0ZJBuqMVYVi-vaIQMBCVd25vnM3-rv3k,2823
128
+ sqlspec/utils/serializers.py,sha256=TKsRryRcYMnb8Z8MGkYGClIxcYvC8CW7MsrPQTJqEcY,154
129
+ sqlspec/utils/singleton.py,sha256=SKnszJi1NPeERgX7IjVIGYAYx4XqR1E_rph3bU6olAU,1047
130
+ sqlspec/utils/sync_tools.py,sha256=f_bjHTXUaDcsNQY63-L7j5xn2MHfzXro-ShzJM-WLUI,8356
131
+ sqlspec/utils/text.py,sha256=W97aX77A3NzG795AHjhdX6zqOBDmvLaXLCno2JIugCo,3081
132
+ sqlspec/utils/type_guards.py,sha256=9C4SRebO4JiQrMzcJZFUA0KjSU48G26RmX6lbijyjBg,30476
133
+ sqlspec-0.18.0.dist-info/METADATA,sha256=SNUm1W2FagyGjCmPrfUcCNBRSyurCMbg60IUMf9iA1E,16822
134
+ sqlspec-0.18.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
135
+ sqlspec-0.18.0.dist-info/entry_points.txt,sha256=G-ZqY1Nuuw3Iys7nXw23f6ILenk_Lt47VdK2mhJCWHg,53
136
+ sqlspec-0.18.0.dist-info/licenses/LICENSE,sha256=MdujfZ6l5HuLz4mElxlu049itenOR3gnhN1_Nd3nVcM,1078
137
+ sqlspec-0.18.0.dist-info/licenses/NOTICE,sha256=Lyir8ozXWov7CyYS4huVaOCNrtgL17P-bNV-5daLntQ,1634
138
+ sqlspec-0.18.0.dist-info/RECORD,,
@@ -1,103 +0,0 @@
1
- """DDL builder utilities."""
2
-
3
- from typing import TYPE_CHECKING, Optional
4
-
5
- from sqlglot import exp
6
-
7
- if TYPE_CHECKING:
8
- from sqlspec.builder._ddl import ColumnDefinition, ConstraintDefinition
9
-
10
- __all__ = ("build_column_expression", "build_constraint_expression")
11
-
12
-
13
- def build_column_expression(col: "ColumnDefinition") -> "exp.Expression":
14
- """Build SQLGlot expression for a column definition."""
15
- col_def = exp.ColumnDef(this=exp.to_identifier(col.name), kind=exp.DataType.build(col.dtype))
16
-
17
- constraints: list[exp.ColumnConstraint] = []
18
-
19
- if col.not_null:
20
- constraints.append(exp.ColumnConstraint(kind=exp.NotNullColumnConstraint()))
21
-
22
- if col.primary_key:
23
- constraints.append(exp.ColumnConstraint(kind=exp.PrimaryKeyColumnConstraint()))
24
-
25
- if col.unique:
26
- constraints.append(exp.ColumnConstraint(kind=exp.UniqueColumnConstraint()))
27
-
28
- if col.default is not None:
29
- default_expr: Optional[exp.Expression] = None
30
- if isinstance(col.default, str):
31
- if col.default.upper() in {"CURRENT_TIMESTAMP", "CURRENT_DATE", "CURRENT_TIME"} or "(" in col.default:
32
- default_expr = exp.maybe_parse(col.default)
33
- else:
34
- default_expr = exp.convert(col.default)
35
- else:
36
- default_expr = exp.convert(col.default)
37
-
38
- constraints.append(exp.ColumnConstraint(kind=default_expr))
39
-
40
- if col.check:
41
- check_expr = exp.Check(this=exp.maybe_parse(col.check))
42
- constraints.append(exp.ColumnConstraint(kind=check_expr))
43
-
44
- if col.comment:
45
- constraints.append(exp.ColumnConstraint(kind=exp.CommentColumnConstraint(this=exp.convert(col.comment))))
46
-
47
- if col.generated:
48
- generated_expr = exp.GeneratedAsIdentityColumnConstraint(this=exp.maybe_parse(col.generated))
49
- constraints.append(exp.ColumnConstraint(kind=generated_expr))
50
-
51
- if col.collate:
52
- constraints.append(exp.ColumnConstraint(kind=exp.CollateColumnConstraint(this=exp.to_identifier(col.collate))))
53
-
54
- if constraints:
55
- col_def.set("constraints", constraints)
56
-
57
- return col_def
58
-
59
-
60
- def build_constraint_expression(constraint: "ConstraintDefinition") -> "Optional[exp.Expression]":
61
- """Build SQLGlot expression for a table constraint."""
62
- if constraint.constraint_type == "PRIMARY KEY":
63
- pk_cols = [exp.to_identifier(col) for col in constraint.columns]
64
- pk_constraint = exp.PrimaryKey(expressions=pk_cols)
65
-
66
- if constraint.name:
67
- return exp.Constraint(this=exp.to_identifier(constraint.name), expression=pk_constraint)
68
- return pk_constraint
69
-
70
- if constraint.constraint_type == "FOREIGN KEY":
71
- fk_cols = [exp.to_identifier(col) for col in constraint.columns]
72
- ref_cols = [exp.to_identifier(col) for col in constraint.references_columns]
73
-
74
- fk_constraint = exp.ForeignKey(
75
- expressions=fk_cols,
76
- reference=exp.Reference(
77
- this=exp.to_table(constraint.references_table) if constraint.references_table else None,
78
- expressions=ref_cols,
79
- on_delete=constraint.on_delete,
80
- on_update=constraint.on_update,
81
- ),
82
- )
83
-
84
- if constraint.name:
85
- return exp.Constraint(this=exp.to_identifier(constraint.name), expression=fk_constraint)
86
- return fk_constraint
87
-
88
- if constraint.constraint_type == "UNIQUE":
89
- unique_cols = [exp.to_identifier(col) for col in constraint.columns]
90
- unique_constraint = exp.UniqueKeyProperty(expressions=unique_cols)
91
-
92
- if constraint.name:
93
- return exp.Constraint(this=exp.to_identifier(constraint.name), expression=unique_constraint)
94
- return unique_constraint
95
-
96
- if constraint.constraint_type == "CHECK":
97
- check_expr = exp.Check(this=exp.maybe_parse(constraint.condition) if constraint.condition else None)
98
-
99
- if constraint.name:
100
- return exp.Constraint(this=exp.to_identifier(constraint.name), expression=check_expr)
101
- return check_expr
102
-
103
- return None