sqlspec 0.26.0__py3-none-any.whl → 0.28.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 (212) hide show
  1. sqlspec/__init__.py +7 -15
  2. sqlspec/_serialization.py +55 -25
  3. sqlspec/_typing.py +155 -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 +880 -0
  7. sqlspec/adapters/adbc/config.py +62 -12
  8. sqlspec/adapters/adbc/data_dictionary.py +74 -2
  9. sqlspec/adapters/adbc/driver.py +226 -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 +44 -50
  13. sqlspec/adapters/aiosqlite/_types.py +1 -1
  14. sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
  15. sqlspec/adapters/aiosqlite/adk/store.py +536 -0
  16. sqlspec/adapters/aiosqlite/config.py +86 -16
  17. sqlspec/adapters/aiosqlite/data_dictionary.py +34 -2
  18. sqlspec/adapters/aiosqlite/driver.py +127 -38
  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 +1 -1
  24. sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
  25. sqlspec/adapters/asyncmy/adk/store.py +503 -0
  26. sqlspec/adapters/asyncmy/config.py +59 -17
  27. sqlspec/adapters/asyncmy/data_dictionary.py +41 -2
  28. sqlspec/adapters/asyncmy/driver.py +293 -62
  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 +460 -0
  36. sqlspec/adapters/asyncpg/config.py +57 -36
  37. sqlspec/adapters/asyncpg/data_dictionary.py +48 -2
  38. sqlspec/adapters/asyncpg/driver.py +153 -23
  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 +585 -0
  44. sqlspec/adapters/bigquery/config.py +36 -11
  45. sqlspec/adapters/bigquery/data_dictionary.py +42 -2
  46. sqlspec/adapters/bigquery/driver.py +489 -144
  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 +55 -23
  50. sqlspec/adapters/duckdb/_types.py +2 -2
  51. sqlspec/adapters/duckdb/adk/__init__.py +14 -0
  52. sqlspec/adapters/duckdb/adk/store.py +563 -0
  53. sqlspec/adapters/duckdb/config.py +79 -21
  54. sqlspec/adapters/duckdb/data_dictionary.py +41 -2
  55. sqlspec/adapters/duckdb/driver.py +225 -44
  56. sqlspec/adapters/duckdb/litestar/__init__.py +5 -0
  57. sqlspec/adapters/duckdb/litestar/store.py +332 -0
  58. sqlspec/adapters/duckdb/pool.py +5 -5
  59. sqlspec/adapters/duckdb/type_converter.py +51 -21
  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 +1628 -0
  64. sqlspec/adapters/oracledb/config.py +120 -36
  65. sqlspec/adapters/oracledb/data_dictionary.py +87 -20
  66. sqlspec/adapters/oracledb/driver.py +475 -86
  67. sqlspec/adapters/oracledb/litestar/__init__.py +5 -0
  68. sqlspec/adapters/oracledb/litestar/store.py +765 -0
  69. sqlspec/adapters/oracledb/migrations.py +316 -25
  70. sqlspec/adapters/oracledb/type_converter.py +91 -16
  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 +483 -0
  75. sqlspec/adapters/psqlpy/config.py +45 -19
  76. sqlspec/adapters/psqlpy/data_dictionary.py +48 -2
  77. sqlspec/adapters/psqlpy/driver.py +108 -41
  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 +40 -11
  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 +962 -0
  85. sqlspec/adapters/psycopg/config.py +65 -37
  86. sqlspec/adapters/psycopg/data_dictionary.py +91 -3
  87. sqlspec/adapters/psycopg/driver.py +200 -78
  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 +582 -0
  95. sqlspec/adapters/sqlite/config.py +85 -16
  96. sqlspec/adapters/sqlite/data_dictionary.py +34 -2
  97. sqlspec/adapters/sqlite/driver.py +120 -52
  98. sqlspec/adapters/sqlite/litestar/__init__.py +5 -0
  99. sqlspec/adapters/sqlite/litestar/store.py +318 -0
  100. sqlspec/adapters/sqlite/pool.py +5 -5
  101. sqlspec/base.py +45 -26
  102. sqlspec/builder/__init__.py +73 -4
  103. sqlspec/builder/_base.py +91 -58
  104. sqlspec/builder/_column.py +5 -5
  105. sqlspec/builder/_ddl.py +98 -89
  106. sqlspec/builder/_delete.py +5 -4
  107. sqlspec/builder/_dml.py +388 -0
  108. sqlspec/{_sql.py → builder/_factory.py} +41 -44
  109. sqlspec/builder/_insert.py +5 -82
  110. sqlspec/builder/{mixins/_join_operations.py → _join.py} +145 -143
  111. sqlspec/builder/_merge.py +446 -11
  112. sqlspec/builder/_parsing_utils.py +9 -11
  113. sqlspec/builder/_select.py +1313 -25
  114. sqlspec/builder/_update.py +11 -42
  115. sqlspec/cli.py +76 -69
  116. sqlspec/config.py +331 -62
  117. sqlspec/core/__init__.py +5 -4
  118. sqlspec/core/cache.py +18 -18
  119. sqlspec/core/compiler.py +6 -8
  120. sqlspec/core/filters.py +55 -47
  121. sqlspec/core/hashing.py +9 -9
  122. sqlspec/core/parameters.py +76 -45
  123. sqlspec/core/result.py +234 -47
  124. sqlspec/core/splitter.py +16 -17
  125. sqlspec/core/statement.py +32 -31
  126. sqlspec/core/type_conversion.py +3 -2
  127. sqlspec/driver/__init__.py +1 -3
  128. sqlspec/driver/_async.py +183 -160
  129. sqlspec/driver/_common.py +197 -109
  130. sqlspec/driver/_sync.py +189 -161
  131. sqlspec/driver/mixins/_result_tools.py +20 -236
  132. sqlspec/driver/mixins/_sql_translator.py +4 -4
  133. sqlspec/exceptions.py +70 -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 +69 -61
  142. sqlspec/extensions/fastapi/__init__.py +21 -0
  143. sqlspec/extensions/fastapi/extension.py +331 -0
  144. sqlspec/extensions/fastapi/providers.py +543 -0
  145. sqlspec/extensions/flask/__init__.py +36 -0
  146. sqlspec/extensions/flask/_state.py +71 -0
  147. sqlspec/extensions/flask/_utils.py +40 -0
  148. sqlspec/extensions/flask/extension.py +389 -0
  149. sqlspec/extensions/litestar/__init__.py +21 -4
  150. sqlspec/extensions/litestar/cli.py +54 -10
  151. sqlspec/extensions/litestar/config.py +56 -266
  152. sqlspec/extensions/litestar/handlers.py +46 -17
  153. sqlspec/extensions/litestar/migrations/0001_create_session_table.py +137 -0
  154. sqlspec/extensions/litestar/migrations/__init__.py +3 -0
  155. sqlspec/extensions/litestar/plugin.py +349 -224
  156. sqlspec/extensions/litestar/providers.py +25 -25
  157. sqlspec/extensions/litestar/store.py +265 -0
  158. sqlspec/extensions/starlette/__init__.py +10 -0
  159. sqlspec/extensions/starlette/_state.py +25 -0
  160. sqlspec/extensions/starlette/_utils.py +52 -0
  161. sqlspec/extensions/starlette/extension.py +254 -0
  162. sqlspec/extensions/starlette/middleware.py +154 -0
  163. sqlspec/loader.py +30 -49
  164. sqlspec/migrations/base.py +200 -76
  165. sqlspec/migrations/commands.py +591 -62
  166. sqlspec/migrations/context.py +6 -9
  167. sqlspec/migrations/fix.py +199 -0
  168. sqlspec/migrations/loaders.py +47 -19
  169. sqlspec/migrations/runner.py +241 -75
  170. sqlspec/migrations/tracker.py +237 -21
  171. sqlspec/migrations/utils.py +51 -3
  172. sqlspec/migrations/validation.py +177 -0
  173. sqlspec/protocols.py +106 -36
  174. sqlspec/storage/_utils.py +85 -0
  175. sqlspec/storage/backends/fsspec.py +133 -107
  176. sqlspec/storage/backends/local.py +78 -51
  177. sqlspec/storage/backends/obstore.py +276 -168
  178. sqlspec/storage/registry.py +75 -39
  179. sqlspec/typing.py +30 -84
  180. sqlspec/utils/__init__.py +25 -4
  181. sqlspec/utils/arrow_helpers.py +81 -0
  182. sqlspec/utils/config_resolver.py +6 -6
  183. sqlspec/utils/correlation.py +4 -5
  184. sqlspec/utils/data_transformation.py +3 -2
  185. sqlspec/utils/deprecation.py +9 -8
  186. sqlspec/utils/fixtures.py +4 -4
  187. sqlspec/utils/logging.py +46 -6
  188. sqlspec/utils/module_loader.py +205 -5
  189. sqlspec/utils/portal.py +311 -0
  190. sqlspec/utils/schema.py +288 -0
  191. sqlspec/utils/serializers.py +113 -4
  192. sqlspec/utils/sync_tools.py +36 -22
  193. sqlspec/utils/text.py +1 -2
  194. sqlspec/utils/type_guards.py +136 -20
  195. sqlspec/utils/version.py +433 -0
  196. {sqlspec-0.26.0.dist-info → sqlspec-0.28.0.dist-info}/METADATA +41 -22
  197. sqlspec-0.28.0.dist-info/RECORD +221 -0
  198. sqlspec/builder/mixins/__init__.py +0 -55
  199. sqlspec/builder/mixins/_cte_and_set_ops.py +0 -253
  200. sqlspec/builder/mixins/_delete_operations.py +0 -50
  201. sqlspec/builder/mixins/_insert_operations.py +0 -282
  202. sqlspec/builder/mixins/_merge_operations.py +0 -698
  203. sqlspec/builder/mixins/_order_limit_operations.py +0 -145
  204. sqlspec/builder/mixins/_pivot_operations.py +0 -157
  205. sqlspec/builder/mixins/_select_operations.py +0 -930
  206. sqlspec/builder/mixins/_update_operations.py +0 -199
  207. sqlspec/builder/mixins/_where_clause.py +0 -1298
  208. sqlspec-0.26.0.dist-info/RECORD +0 -157
  209. sqlspec-0.26.0.dist-info/licenses/NOTICE +0 -29
  210. {sqlspec-0.26.0.dist-info → sqlspec-0.28.0.dist-info}/WHEEL +0 -0
  211. {sqlspec-0.26.0.dist-info → sqlspec-0.28.0.dist-info}/entry_points.txt +0 -0
  212. {sqlspec-0.26.0.dist-info → sqlspec-0.28.0.dist-info}/licenses/LICENSE +0 -0
sqlspec/builder/_ddl.py CHANGED
@@ -4,7 +4,7 @@ Provides builders for DDL operations including CREATE, DROP, ALTER,
4
4
  TRUNCATE, and other schema manipulation statements.
5
5
  """
6
6
 
7
- from typing import TYPE_CHECKING, Any, Optional, Union
7
+ from typing import TYPE_CHECKING, Any, Union
8
8
 
9
9
  from sqlglot import exp
10
10
  from sqlglot.dialects.dialect import DialectType
@@ -89,7 +89,7 @@ def build_column_expression(col: "ColumnDefinition") -> "exp.Expression":
89
89
  constraints.append(exp.ColumnConstraint(kind=exp.UniqueColumnConstraint()))
90
90
 
91
91
  if col.default is not None:
92
- default_expr: Optional[exp.Expression] = None
92
+ default_expr: exp.Expression | None = None
93
93
  if isinstance(col.default, str):
94
94
  default_upper = col.default.upper()
95
95
  if default_upper == CURRENT_TIMESTAMP_KEYWORD:
@@ -127,7 +127,7 @@ def build_column_expression(col: "ColumnDefinition") -> "exp.Expression":
127
127
  return col_def
128
128
 
129
129
 
130
- def build_constraint_expression(constraint: "ConstraintDefinition") -> "Optional[exp.Expression]":
130
+ def build_constraint_expression(constraint: "ConstraintDefinition") -> "exp.Expression | None":
131
131
  """Build SQLGlot expression for a table constraint."""
132
132
  if constraint.constraint_type == CONSTRAINT_TYPE_PRIMARY_KEY:
133
133
  pk_constraint = exp.PrimaryKey(expressions=[exp.to_identifier(col) for col in constraint.columns])
@@ -175,7 +175,7 @@ class DDLBuilder(QueryBuilder):
175
175
 
176
176
  def __init__(self, dialect: DialectType = None) -> None:
177
177
  super().__init__(dialect=dialect)
178
- self._expression: Optional[exp.Expression] = None
178
+ self._expression: exp.Expression | None = None
179
179
 
180
180
  def _create_base_expression(self) -> exp.Expression:
181
181
  msg = "Subclasses must implement _create_base_expression."
@@ -190,7 +190,7 @@ class DDLBuilder(QueryBuilder):
190
190
  self._expression = self._create_base_expression()
191
191
  return super().build()
192
192
 
193
- def to_statement(self, config: "Optional[StatementConfig]" = None) -> "SQL":
193
+ def to_statement(self, config: "StatementConfig | None" = None) -> "SQL":
194
194
  return super().to_statement(config=config)
195
195
 
196
196
 
@@ -215,15 +215,15 @@ class ColumnDefinition:
215
215
  self,
216
216
  name: str,
217
217
  dtype: str,
218
- default: "Optional[Any]" = None,
218
+ default: "Any | None" = None,
219
219
  not_null: bool = False,
220
220
  primary_key: bool = False,
221
221
  unique: bool = False,
222
222
  auto_increment: bool = False,
223
- comment: "Optional[str]" = None,
224
- check: "Optional[str]" = None,
225
- generated: "Optional[str]" = None,
226
- collate: "Optional[str]" = None,
223
+ comment: "str | None" = None,
224
+ check: "str | None" = None,
225
+ generated: "str | None" = None,
226
+ collate: "str | None" = None,
227
227
  ) -> None:
228
228
  self.name = name
229
229
  self.dtype = dtype
@@ -257,13 +257,13 @@ class ConstraintDefinition:
257
257
  def __init__(
258
258
  self,
259
259
  constraint_type: str,
260
- name: "Optional[str]" = None,
261
- columns: "Optional[list[str]]" = None,
262
- references_table: "Optional[str]" = None,
263
- references_columns: "Optional[list[str]]" = None,
264
- condition: "Optional[str]" = None,
265
- on_delete: "Optional[str]" = None,
266
- on_update: "Optional[str]" = None,
260
+ name: "str | None" = None,
261
+ columns: "list[str] | None" = None,
262
+ references_table: "str | None" = None,
263
+ references_columns: "list[str] | None" = None,
264
+ condition: "str | None" = None,
265
+ on_delete: "str | None" = None,
266
+ on_update: "str | None" = None,
267
267
  deferrable: bool = False,
268
268
  initially_deferred: bool = False,
269
269
  ) -> None:
@@ -314,10 +314,10 @@ class CreateTable(DDLBuilder):
314
314
  self._columns: list[ColumnDefinition] = []
315
315
  self._constraints: list[ConstraintDefinition] = []
316
316
  self._table_options: dict[str, Any] = {}
317
- self._schema: Optional[str] = None
318
- self._tablespace: Optional[str] = None
319
- self._like_table: Optional[str] = None
320
- self._partition_by: Optional[str] = None
317
+ self._schema: str | None = None
318
+ self._tablespace: str | None = None
319
+ self._like_table: str | None = None
320
+ self._partition_by: str | None = None
321
321
 
322
322
  def in_schema(self, schema_name: str) -> "Self":
323
323
  """Set the schema for the table."""
@@ -349,19 +349,28 @@ class CreateTable(DDLBuilder):
349
349
  self._partition_by = partition_spec
350
350
  return self
351
351
 
352
+ @property
353
+ def columns(self) -> "list[ColumnDefinition]":
354
+ """Get the list of column definitions for this table.
355
+
356
+ Returns:
357
+ List of ColumnDefinition objects.
358
+ """
359
+ return self._columns
360
+
352
361
  def column(
353
362
  self,
354
363
  name: str,
355
364
  dtype: str,
356
- default: "Optional[Any]" = None,
365
+ default: "Any | None" = None,
357
366
  not_null: bool = False,
358
367
  primary_key: bool = False,
359
368
  unique: bool = False,
360
369
  auto_increment: bool = False,
361
- comment: "Optional[str]" = None,
362
- check: "Optional[str]" = None,
363
- generated: "Optional[str]" = None,
364
- collate: "Optional[str]" = None,
370
+ comment: "str | None" = None,
371
+ check: "str | None" = None,
372
+ generated: "str | None" = None,
373
+ collate: "str | None" = None,
365
374
  ) -> "Self":
366
375
  """Add a column definition to the table."""
367
376
  if not name:
@@ -394,7 +403,7 @@ class CreateTable(DDLBuilder):
394
403
 
395
404
  return self
396
405
 
397
- def primary_key_constraint(self, columns: "Union[str, list[str]]", name: "Optional[str]" = None) -> "Self":
406
+ def primary_key_constraint(self, columns: "str | list[str]", name: "str | None" = None) -> "Self":
398
407
  """Add a primary key constraint."""
399
408
  col_list = [columns] if isinstance(columns, str) else list(columns)
400
409
 
@@ -414,12 +423,12 @@ class CreateTable(DDLBuilder):
414
423
 
415
424
  def foreign_key_constraint(
416
425
  self,
417
- columns: "Union[str, list[str]]",
426
+ columns: "str | list[str]",
418
427
  references_table: str,
419
- references_columns: "Union[str, list[str]]",
420
- name: "Optional[str]" = None,
421
- on_delete: "Optional[str]" = None,
422
- on_update: "Optional[str]" = None,
428
+ references_columns: "str | list[str]",
429
+ name: "str | None" = None,
430
+ on_delete: "str | None" = None,
431
+ on_update: "str | None" = None,
423
432
  deferrable: bool = False,
424
433
  initially_deferred: bool = False,
425
434
  ) -> "Self":
@@ -449,7 +458,7 @@ class CreateTable(DDLBuilder):
449
458
  self._constraints.append(constraint)
450
459
  return self
451
460
 
452
- def unique_constraint(self, columns: "Union[str, list[str]]", name: "Optional[str]" = None) -> "Self":
461
+ def unique_constraint(self, columns: "str | list[str]", name: "str | None" = None) -> "Self":
453
462
  """Add a unique constraint."""
454
463
  col_list = [columns] if isinstance(columns, str) else list(columns)
455
464
 
@@ -461,7 +470,7 @@ class CreateTable(DDLBuilder):
461
470
  self._constraints.append(constraint)
462
471
  return self
463
472
 
464
- def check_constraint(self, condition: Union[str, "ColumnExpression"], name: "Optional[str]" = None) -> "Self":
473
+ def check_constraint(self, condition: Union[str, "ColumnExpression"], name: "str | None" = None) -> "Self":
465
474
  """Add a check constraint."""
466
475
  if not condition:
467
476
  self._raise_sql_builder_error("Check constraint must have a condition")
@@ -563,11 +572,11 @@ class CreateTable(DDLBuilder):
563
572
  """Check if table already has a primary key constraint."""
564
573
  return any(c.constraint_type == CONSTRAINT_TYPE_PRIMARY_KEY for c in self._constraints)
565
574
 
566
- def _find_primary_key_constraint(self) -> "Optional[ConstraintDefinition]":
575
+ def _find_primary_key_constraint(self) -> "ConstraintDefinition | None":
567
576
  """Find existing primary key constraint."""
568
577
  return next((c for c in self._constraints if c.constraint_type == CONSTRAINT_TYPE_PRIMARY_KEY), None)
569
578
 
570
- def _validate_foreign_key_action(self, action: "Optional[str]", action_type: str) -> None:
579
+ def _validate_foreign_key_action(self, action: "str | None", action_type: str) -> None:
571
580
  """Validate foreign key action (ON DELETE or ON UPDATE)."""
572
581
  if action and action.upper() not in VALID_FOREIGN_KEY_ACTIONS:
573
582
  self._raise_sql_builder_error(f"Invalid {action_type} action: {action}")
@@ -596,7 +605,7 @@ class DropTable(DDLBuilder):
596
605
  super().__init__(dialect=dialect)
597
606
  self._table_name = table_name
598
607
  self._if_exists = False
599
- self._cascade: Optional[bool] = None
608
+ self._cascade: bool | None = None
600
609
 
601
610
  def table(self, name: str) -> Self:
602
611
  self._table_name = name
@@ -636,9 +645,9 @@ class DropIndex(DDLBuilder):
636
645
  """
637
646
  super().__init__(dialect=dialect)
638
647
  self._index_name = index_name
639
- self._table_name: Optional[str] = None
648
+ self._table_name: str | None = None
640
649
  self._if_exists = False
641
- self._cascade: Optional[bool] = None
650
+ self._cascade: bool | None = None
642
651
 
643
652
  def name(self, index_name: str) -> Self:
644
653
  self._index_name = index_name
@@ -687,7 +696,7 @@ class DropView(DDLBuilder):
687
696
  super().__init__(dialect=dialect)
688
697
  self._view_name = view_name
689
698
  self._if_exists = False
690
- self._cascade: Optional[bool] = None
699
+ self._cascade: bool | None = None
691
700
 
692
701
  def name(self, view_name: str) -> Self:
693
702
  self._view_name = view_name
@@ -728,7 +737,7 @@ class DropSchema(DDLBuilder):
728
737
  super().__init__(dialect=dialect)
729
738
  self._schema_name = schema_name
730
739
  self._if_exists = False
731
- self._cascade: Optional[bool] = None
740
+ self._cascade: bool | None = None
732
741
 
733
742
  def name(self, schema_name: str) -> Self:
734
743
  self._schema_name = schema_name
@@ -768,12 +777,12 @@ class CreateIndex(DDLBuilder):
768
777
  """
769
778
  super().__init__(dialect=dialect)
770
779
  self._index_name = index_name
771
- self._table_name: Optional[str] = None
772
- self._columns: list[Union[str, exp.Ordered, exp.Expression]] = []
780
+ self._table_name: str | None = None
781
+ self._columns: list[str | exp.Ordered | exp.Expression] = []
773
782
  self._unique = False
774
783
  self._if_not_exists = False
775
- self._using: Optional[str] = None
776
- self._where: Optional[Union[str, exp.Expression]] = None
784
+ self._using: str | None = None
785
+ self._where: str | exp.Expression | None = None
777
786
 
778
787
  def name(self, index_name: str) -> Self:
779
788
  self._index_name = index_name
@@ -783,11 +792,11 @@ class CreateIndex(DDLBuilder):
783
792
  self._table_name = table_name
784
793
  return self
785
794
 
786
- def columns(self, *cols: Union[str, exp.Ordered, exp.Expression]) -> Self:
795
+ def columns(self, *cols: str | exp.Ordered | exp.Expression) -> Self:
787
796
  self._columns.extend(cols)
788
797
  return self
789
798
 
790
- def expressions(self, *exprs: Union[str, exp.Expression]) -> Self:
799
+ def expressions(self, *exprs: str | exp.Expression) -> Self:
791
800
  self._columns.extend(exprs)
792
801
  return self
793
802
 
@@ -803,7 +812,7 @@ class CreateIndex(DDLBuilder):
803
812
  self._using = method
804
813
  return self
805
814
 
806
- def where(self, condition: Union[str, exp.Expression]) -> Self:
815
+ def where(self, condition: str | exp.Expression) -> Self:
807
816
  self._where = condition
808
817
  return self
809
818
 
@@ -845,8 +854,8 @@ class Truncate(DDLBuilder):
845
854
  """
846
855
  super().__init__(dialect=dialect)
847
856
  self._table_name = table_name
848
- self._cascade: Optional[bool] = None
849
- self._identity: Optional[str] = None
857
+ self._cascade: bool | None = None
858
+ self._identity: str | None = None
850
859
 
851
860
  def table(self, name: str) -> Self:
852
861
  self._table_name = name
@@ -894,15 +903,15 @@ class AlterOperation:
894
903
  def __init__(
895
904
  self,
896
905
  operation_type: str,
897
- column_name: "Optional[str]" = None,
898
- column_definition: "Optional[ColumnDefinition]" = None,
899
- constraint_name: "Optional[str]" = None,
900
- constraint_definition: "Optional[ConstraintDefinition]" = None,
901
- new_type: "Optional[str]" = None,
902
- new_name: "Optional[str]" = None,
903
- after_column: "Optional[str]" = None,
906
+ column_name: "str | None" = None,
907
+ column_definition: "ColumnDefinition | None" = None,
908
+ constraint_name: "str | None" = None,
909
+ constraint_definition: "ConstraintDefinition | None" = None,
910
+ new_type: "str | None" = None,
911
+ new_name: "str | None" = None,
912
+ after_column: "str | None" = None,
904
913
  first: bool = False,
905
- using_expression: "Optional[str]" = None,
914
+ using_expression: "str | None" = None,
906
915
  ) -> None:
907
916
  self.operation_type = operation_type
908
917
  self.column_name = column_name
@@ -931,7 +940,7 @@ class CreateSchema(DDLBuilder):
931
940
  super().__init__(dialect=dialect)
932
941
  self._schema_name = schema_name
933
942
  self._if_not_exists = False
934
- self._authorization: Optional[str] = None
943
+ self._authorization: str | None = None
935
944
 
936
945
  def name(self, schema_name: str) -> Self:
937
946
  self._schema_name = schema_name
@@ -986,10 +995,10 @@ class CreateTableAsSelect(DDLBuilder):
986
995
 
987
996
  def __init__(self, dialect: DialectType = None) -> None:
988
997
  super().__init__(dialect=dialect)
989
- self._table_name: Optional[str] = None
998
+ self._table_name: str | None = None
990
999
  self._if_not_exists = False
991
1000
  self._columns: list[str] = []
992
- self._select_query: Optional[object] = None
1001
+ self._select_query: object | None = None
993
1002
 
994
1003
  def name(self, table_name: str) -> Self:
995
1004
  self._table_name = table_name
@@ -1003,7 +1012,7 @@ class CreateTableAsSelect(DDLBuilder):
1003
1012
  self._columns = list(cols)
1004
1013
  return self
1005
1014
 
1006
- def as_select(self, select_query: "Union[str, exp.Expression]") -> Self:
1015
+ def as_select(self, select_query: "str | exp.Expression") -> Self:
1007
1016
  self._select_query = select_query
1008
1017
  return self
1009
1018
 
@@ -1080,12 +1089,12 @@ class CreateMaterializedView(DDLBuilder):
1080
1089
  self._view_name = view_name
1081
1090
  self._if_not_exists = False
1082
1091
  self._columns: list[str] = []
1083
- self._select_query: Optional[Union[str, exp.Expression]] = None
1084
- self._with_data: Optional[bool] = None
1085
- self._refresh_mode: Optional[str] = None
1092
+ self._select_query: str | exp.Expression | None = None
1093
+ self._with_data: bool | None = None
1094
+ self._refresh_mode: str | None = None
1086
1095
  self._storage_parameters: dict[str, Any] = {}
1087
- self._tablespace: Optional[str] = None
1088
- self._using_index: Optional[str] = None
1096
+ self._tablespace: str | None = None
1097
+ self._using_index: str | None = None
1089
1098
  self._hints: list[str] = []
1090
1099
 
1091
1100
  def name(self, view_name: str) -> Self:
@@ -1100,7 +1109,7 @@ class CreateMaterializedView(DDLBuilder):
1100
1109
  self._columns = list(cols)
1101
1110
  return self
1102
1111
 
1103
- def as_select(self, select_query: "Union[str, exp.Expression]") -> Self:
1112
+ def as_select(self, select_query: "str | exp.Expression") -> Self:
1104
1113
  self._select_query = select_query
1105
1114
  return self
1106
1115
 
@@ -1205,7 +1214,7 @@ class CreateView(DDLBuilder):
1205
1214
  self._view_name = view_name
1206
1215
  self._if_not_exists = False
1207
1216
  self._columns: list[str] = []
1208
- self._select_query: Optional[Union[str, exp.Expression]] = None
1217
+ self._select_query: str | exp.Expression | None = None
1209
1218
  self._hints: list[str] = []
1210
1219
 
1211
1220
  def name(self, view_name: str) -> Self:
@@ -1220,7 +1229,7 @@ class CreateView(DDLBuilder):
1220
1229
  self._columns = list(cols)
1221
1230
  return self
1222
1231
 
1223
- def as_select(self, select_query: "Union[str, exp.Expression]") -> Self:
1232
+ def as_select(self, select_query: "str | exp.Expression") -> Self:
1224
1233
  self._select_query = select_query
1225
1234
  return self
1226
1235
 
@@ -1292,7 +1301,7 @@ class AlterTable(DDLBuilder):
1292
1301
  super().__init__(dialect=dialect)
1293
1302
  self._table_name = table_name
1294
1303
  self._operations: list[AlterOperation] = []
1295
- self._schema: Optional[str] = None
1304
+ self._schema: str | None = None
1296
1305
  self._if_exists = False
1297
1306
 
1298
1307
  def if_exists(self) -> "Self":
@@ -1304,11 +1313,11 @@ class AlterTable(DDLBuilder):
1304
1313
  self,
1305
1314
  name: str,
1306
1315
  dtype: str,
1307
- default: "Optional[Any]" = None,
1316
+ default: "Any | None" = None,
1308
1317
  not_null: bool = False,
1309
1318
  unique: bool = False,
1310
- comment: "Optional[str]" = None,
1311
- after: "Optional[str]" = None,
1319
+ comment: "str | None" = None,
1320
+ after: "str | None" = None,
1312
1321
  first: bool = False,
1313
1322
  ) -> "Self":
1314
1323
  """Add a new column to the table."""
@@ -1339,7 +1348,7 @@ class AlterTable(DDLBuilder):
1339
1348
  self._operations.append(operation)
1340
1349
  return self
1341
1350
 
1342
- def alter_column_type(self, name: str, new_type: str, using: "Optional[str]" = None) -> "Self":
1351
+ def alter_column_type(self, name: str, new_type: str, using: "str | None" = None) -> "Self":
1343
1352
  """Change the type of an existing column."""
1344
1353
  if not name:
1345
1354
  self._raise_sql_builder_error("Column name must be a non-empty string")
@@ -1370,13 +1379,13 @@ class AlterTable(DDLBuilder):
1370
1379
  def add_constraint(
1371
1380
  self,
1372
1381
  constraint_type: str,
1373
- columns: "Optional[Union[str, list[str]]]" = None,
1374
- name: "Optional[str]" = None,
1375
- references_table: "Optional[str]" = None,
1376
- references_columns: "Optional[Union[str, list[str]]]" = None,
1377
- condition: "Optional[Union[str, ColumnExpression]]" = None,
1378
- on_delete: "Optional[str]" = None,
1379
- on_update: "Optional[str]" = None,
1382
+ columns: "str | list[str] | None" = None,
1383
+ name: "str | None" = None,
1384
+ references_table: "str | None" = None,
1385
+ references_columns: "str | list[str] | None" = None,
1386
+ condition: "str | ColumnExpression | None" = None,
1387
+ on_delete: "str | None" = None,
1388
+ on_update: "str | None" = None,
1380
1389
  ) -> "Self":
1381
1390
  """Add a constraint to the table.
1382
1391
 
@@ -1401,7 +1410,7 @@ class AlterTable(DDLBuilder):
1401
1410
  if references_columns is not None:
1402
1411
  ref_col_list = [references_columns] if isinstance(references_columns, str) else list(references_columns)
1403
1412
 
1404
- condition_str: Optional[str] = None
1413
+ condition_str: str | None = None
1405
1414
  if condition is not None:
1406
1415
  if has_sqlglot_expression(condition):
1407
1416
  sqlglot_expr = condition.sqlglot_expression
@@ -1514,7 +1523,7 @@ class AlterTable(DDLBuilder):
1514
1523
  if not op.column_definition or op.column_definition.default is None:
1515
1524
  self._raise_sql_builder_error("Default value required for SET DEFAULT")
1516
1525
  default_val = op.column_definition.default
1517
- default_expr: Optional[exp.Expression]
1526
+ default_expr: exp.Expression | None
1518
1527
  if isinstance(default_val, str):
1519
1528
  if self._is_sql_function_default(default_val):
1520
1529
  default_expr = exp.maybe_parse(default_val)
@@ -1557,10 +1566,10 @@ class CommentOn(DDLBuilder):
1557
1566
  dialect: SQL dialect to use
1558
1567
  """
1559
1568
  super().__init__(dialect=dialect)
1560
- self._target_type: Optional[str] = None
1561
- self._table: Optional[str] = None
1562
- self._column: Optional[str] = None
1563
- self._comment: Optional[str] = None
1569
+ self._target_type: str | None = None
1570
+ self._table: str | None = None
1571
+ self._column: str | None = None
1572
+ self._comment: str | None = None
1564
1573
 
1565
1574
  def on_table(self, table: str) -> Self:
1566
1575
  self._target_type = "TABLE"
@@ -1605,7 +1614,7 @@ class RenameTable(DDLBuilder):
1605
1614
  """
1606
1615
  super().__init__(dialect=dialect)
1607
1616
  self._old_name = old_name
1608
- self._new_name: Optional[str] = None
1617
+ self._new_name: str | None = None
1609
1618
 
1610
1619
  def table(self, old_name: str) -> Self:
1611
1620
  self._old_name = old_name
@@ -4,12 +4,13 @@ Provides a fluent interface for building SQL DELETE queries with
4
4
  parameter binding and validation.
5
5
  """
6
6
 
7
- from typing import Any, Optional
7
+ from typing import Any
8
8
 
9
9
  from sqlglot import exp
10
10
 
11
11
  from sqlspec.builder._base import QueryBuilder, SafeQuery
12
- from sqlspec.builder.mixins import DeleteFromClauseMixin, ReturningClauseMixin, WhereClauseMixin
12
+ from sqlspec.builder._dml import DeleteFromClauseMixin
13
+ from sqlspec.builder._select import ReturningClauseMixin, WhereClauseMixin
13
14
  from sqlspec.core.result import SQLResult
14
15
  from sqlspec.exceptions import SQLBuilderError
15
16
 
@@ -24,9 +25,9 @@ class Delete(QueryBuilder, WhereClauseMixin, ReturningClauseMixin, DeleteFromCla
24
25
  """
25
26
 
26
27
  __slots__ = ("_table",)
27
- _expression: Optional[exp.Expression]
28
+ _expression: exp.Expression | None
28
29
 
29
- def __init__(self, table: Optional[str] = None, **kwargs: Any) -> None:
30
+ def __init__(self, table: str | None = None, **kwargs: Any) -> None:
30
31
  """Initialize DELETE with optional table.
31
32
 
32
33
  Args: