sqlspec 0.25.0__py3-none-any.whl → 0.27.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of sqlspec might be problematic. Click here for more details.

Files changed (199) hide show
  1. sqlspec/__init__.py +7 -15
  2. sqlspec/_serialization.py +256 -24
  3. sqlspec/_typing.py +71 -52
  4. sqlspec/adapters/adbc/_types.py +1 -1
  5. sqlspec/adapters/adbc/adk/__init__.py +5 -0
  6. sqlspec/adapters/adbc/adk/store.py +870 -0
  7. sqlspec/adapters/adbc/config.py +69 -12
  8. sqlspec/adapters/adbc/data_dictionary.py +340 -0
  9. sqlspec/adapters/adbc/driver.py +266 -58
  10. sqlspec/adapters/adbc/litestar/__init__.py +5 -0
  11. sqlspec/adapters/adbc/litestar/store.py +504 -0
  12. sqlspec/adapters/adbc/type_converter.py +153 -0
  13. sqlspec/adapters/aiosqlite/_types.py +1 -1
  14. sqlspec/adapters/aiosqlite/adk/__init__.py +5 -0
  15. sqlspec/adapters/aiosqlite/adk/store.py +527 -0
  16. sqlspec/adapters/aiosqlite/config.py +88 -15
  17. sqlspec/adapters/aiosqlite/data_dictionary.py +149 -0
  18. sqlspec/adapters/aiosqlite/driver.py +143 -40
  19. sqlspec/adapters/aiosqlite/litestar/__init__.py +5 -0
  20. sqlspec/adapters/aiosqlite/litestar/store.py +281 -0
  21. sqlspec/adapters/aiosqlite/pool.py +7 -7
  22. sqlspec/adapters/asyncmy/__init__.py +7 -1
  23. sqlspec/adapters/asyncmy/_types.py +2 -2
  24. sqlspec/adapters/asyncmy/adk/__init__.py +5 -0
  25. sqlspec/adapters/asyncmy/adk/store.py +493 -0
  26. sqlspec/adapters/asyncmy/config.py +68 -23
  27. sqlspec/adapters/asyncmy/data_dictionary.py +161 -0
  28. sqlspec/adapters/asyncmy/driver.py +313 -58
  29. sqlspec/adapters/asyncmy/litestar/__init__.py +5 -0
  30. sqlspec/adapters/asyncmy/litestar/store.py +296 -0
  31. sqlspec/adapters/asyncpg/__init__.py +2 -1
  32. sqlspec/adapters/asyncpg/_type_handlers.py +71 -0
  33. sqlspec/adapters/asyncpg/_types.py +11 -7
  34. sqlspec/adapters/asyncpg/adk/__init__.py +5 -0
  35. sqlspec/adapters/asyncpg/adk/store.py +450 -0
  36. sqlspec/adapters/asyncpg/config.py +59 -35
  37. sqlspec/adapters/asyncpg/data_dictionary.py +173 -0
  38. sqlspec/adapters/asyncpg/driver.py +170 -25
  39. sqlspec/adapters/asyncpg/litestar/__init__.py +5 -0
  40. sqlspec/adapters/asyncpg/litestar/store.py +253 -0
  41. sqlspec/adapters/bigquery/_types.py +1 -1
  42. sqlspec/adapters/bigquery/adk/__init__.py +5 -0
  43. sqlspec/adapters/bigquery/adk/store.py +576 -0
  44. sqlspec/adapters/bigquery/config.py +27 -10
  45. sqlspec/adapters/bigquery/data_dictionary.py +149 -0
  46. sqlspec/adapters/bigquery/driver.py +368 -142
  47. sqlspec/adapters/bigquery/litestar/__init__.py +5 -0
  48. sqlspec/adapters/bigquery/litestar/store.py +327 -0
  49. sqlspec/adapters/bigquery/type_converter.py +125 -0
  50. sqlspec/adapters/duckdb/_types.py +1 -1
  51. sqlspec/adapters/duckdb/adk/__init__.py +14 -0
  52. sqlspec/adapters/duckdb/adk/store.py +553 -0
  53. sqlspec/adapters/duckdb/config.py +80 -20
  54. sqlspec/adapters/duckdb/data_dictionary.py +163 -0
  55. sqlspec/adapters/duckdb/driver.py +167 -45
  56. sqlspec/adapters/duckdb/litestar/__init__.py +5 -0
  57. sqlspec/adapters/duckdb/litestar/store.py +332 -0
  58. sqlspec/adapters/duckdb/pool.py +4 -4
  59. sqlspec/adapters/duckdb/type_converter.py +133 -0
  60. sqlspec/adapters/oracledb/_numpy_handlers.py +133 -0
  61. sqlspec/adapters/oracledb/_types.py +20 -2
  62. sqlspec/adapters/oracledb/adk/__init__.py +5 -0
  63. sqlspec/adapters/oracledb/adk/store.py +1745 -0
  64. sqlspec/adapters/oracledb/config.py +122 -32
  65. sqlspec/adapters/oracledb/data_dictionary.py +509 -0
  66. sqlspec/adapters/oracledb/driver.py +353 -91
  67. sqlspec/adapters/oracledb/litestar/__init__.py +5 -0
  68. sqlspec/adapters/oracledb/litestar/store.py +767 -0
  69. sqlspec/adapters/oracledb/migrations.py +348 -73
  70. sqlspec/adapters/oracledb/type_converter.py +207 -0
  71. sqlspec/adapters/psqlpy/_type_handlers.py +44 -0
  72. sqlspec/adapters/psqlpy/_types.py +2 -1
  73. sqlspec/adapters/psqlpy/adk/__init__.py +5 -0
  74. sqlspec/adapters/psqlpy/adk/store.py +482 -0
  75. sqlspec/adapters/psqlpy/config.py +46 -17
  76. sqlspec/adapters/psqlpy/data_dictionary.py +172 -0
  77. sqlspec/adapters/psqlpy/driver.py +123 -209
  78. sqlspec/adapters/psqlpy/litestar/__init__.py +5 -0
  79. sqlspec/adapters/psqlpy/litestar/store.py +272 -0
  80. sqlspec/adapters/psqlpy/type_converter.py +102 -0
  81. sqlspec/adapters/psycopg/_type_handlers.py +80 -0
  82. sqlspec/adapters/psycopg/_types.py +2 -1
  83. sqlspec/adapters/psycopg/adk/__init__.py +5 -0
  84. sqlspec/adapters/psycopg/adk/store.py +944 -0
  85. sqlspec/adapters/psycopg/config.py +69 -35
  86. sqlspec/adapters/psycopg/data_dictionary.py +331 -0
  87. sqlspec/adapters/psycopg/driver.py +238 -81
  88. sqlspec/adapters/psycopg/litestar/__init__.py +5 -0
  89. sqlspec/adapters/psycopg/litestar/store.py +554 -0
  90. sqlspec/adapters/sqlite/__init__.py +2 -1
  91. sqlspec/adapters/sqlite/_type_handlers.py +86 -0
  92. sqlspec/adapters/sqlite/_types.py +1 -1
  93. sqlspec/adapters/sqlite/adk/__init__.py +5 -0
  94. sqlspec/adapters/sqlite/adk/store.py +572 -0
  95. sqlspec/adapters/sqlite/config.py +87 -15
  96. sqlspec/adapters/sqlite/data_dictionary.py +149 -0
  97. sqlspec/adapters/sqlite/driver.py +137 -54
  98. sqlspec/adapters/sqlite/litestar/__init__.py +5 -0
  99. sqlspec/adapters/sqlite/litestar/store.py +318 -0
  100. sqlspec/adapters/sqlite/pool.py +18 -9
  101. sqlspec/base.py +45 -26
  102. sqlspec/builder/__init__.py +73 -4
  103. sqlspec/builder/_base.py +162 -89
  104. sqlspec/builder/_column.py +62 -29
  105. sqlspec/builder/_ddl.py +180 -121
  106. sqlspec/builder/_delete.py +5 -4
  107. sqlspec/builder/_dml.py +388 -0
  108. sqlspec/{_sql.py → builder/_factory.py} +53 -94
  109. sqlspec/builder/_insert.py +32 -131
  110. sqlspec/builder/_join.py +375 -0
  111. sqlspec/builder/_merge.py +446 -11
  112. sqlspec/builder/_parsing_utils.py +111 -17
  113. sqlspec/builder/_select.py +1457 -24
  114. sqlspec/builder/_update.py +11 -42
  115. sqlspec/cli.py +307 -194
  116. sqlspec/config.py +252 -67
  117. sqlspec/core/__init__.py +5 -4
  118. sqlspec/core/cache.py +17 -17
  119. sqlspec/core/compiler.py +62 -9
  120. sqlspec/core/filters.py +37 -37
  121. sqlspec/core/hashing.py +9 -9
  122. sqlspec/core/parameters.py +83 -48
  123. sqlspec/core/result.py +102 -46
  124. sqlspec/core/splitter.py +16 -17
  125. sqlspec/core/statement.py +36 -30
  126. sqlspec/core/type_conversion.py +235 -0
  127. sqlspec/driver/__init__.py +7 -6
  128. sqlspec/driver/_async.py +188 -151
  129. sqlspec/driver/_common.py +285 -80
  130. sqlspec/driver/_sync.py +188 -152
  131. sqlspec/driver/mixins/_result_tools.py +20 -236
  132. sqlspec/driver/mixins/_sql_translator.py +4 -4
  133. sqlspec/exceptions.py +75 -7
  134. sqlspec/extensions/adk/__init__.py +53 -0
  135. sqlspec/extensions/adk/_types.py +51 -0
  136. sqlspec/extensions/adk/converters.py +172 -0
  137. sqlspec/extensions/adk/migrations/0001_create_adk_tables.py +144 -0
  138. sqlspec/extensions/adk/migrations/__init__.py +0 -0
  139. sqlspec/extensions/adk/service.py +181 -0
  140. sqlspec/extensions/adk/store.py +536 -0
  141. sqlspec/extensions/aiosql/adapter.py +73 -53
  142. sqlspec/extensions/litestar/__init__.py +21 -4
  143. sqlspec/extensions/litestar/cli.py +54 -10
  144. sqlspec/extensions/litestar/config.py +59 -266
  145. sqlspec/extensions/litestar/handlers.py +46 -17
  146. sqlspec/extensions/litestar/migrations/0001_create_session_table.py +137 -0
  147. sqlspec/extensions/litestar/migrations/__init__.py +3 -0
  148. sqlspec/extensions/litestar/plugin.py +324 -223
  149. sqlspec/extensions/litestar/providers.py +25 -25
  150. sqlspec/extensions/litestar/store.py +265 -0
  151. sqlspec/loader.py +30 -49
  152. sqlspec/migrations/__init__.py +4 -3
  153. sqlspec/migrations/base.py +302 -39
  154. sqlspec/migrations/commands.py +611 -144
  155. sqlspec/migrations/context.py +142 -0
  156. sqlspec/migrations/fix.py +199 -0
  157. sqlspec/migrations/loaders.py +68 -23
  158. sqlspec/migrations/runner.py +543 -107
  159. sqlspec/migrations/tracker.py +237 -21
  160. sqlspec/migrations/utils.py +51 -3
  161. sqlspec/migrations/validation.py +177 -0
  162. sqlspec/protocols.py +66 -36
  163. sqlspec/storage/_utils.py +98 -0
  164. sqlspec/storage/backends/fsspec.py +134 -106
  165. sqlspec/storage/backends/local.py +78 -51
  166. sqlspec/storage/backends/obstore.py +278 -162
  167. sqlspec/storage/registry.py +75 -39
  168. sqlspec/typing.py +16 -84
  169. sqlspec/utils/config_resolver.py +153 -0
  170. sqlspec/utils/correlation.py +4 -5
  171. sqlspec/utils/data_transformation.py +3 -2
  172. sqlspec/utils/deprecation.py +9 -8
  173. sqlspec/utils/fixtures.py +4 -4
  174. sqlspec/utils/logging.py +46 -6
  175. sqlspec/utils/module_loader.py +2 -2
  176. sqlspec/utils/schema.py +288 -0
  177. sqlspec/utils/serializers.py +50 -2
  178. sqlspec/utils/sync_tools.py +21 -17
  179. sqlspec/utils/text.py +1 -2
  180. sqlspec/utils/type_guards.py +111 -20
  181. sqlspec/utils/version.py +433 -0
  182. {sqlspec-0.25.0.dist-info → sqlspec-0.27.0.dist-info}/METADATA +40 -21
  183. sqlspec-0.27.0.dist-info/RECORD +207 -0
  184. sqlspec/builder/mixins/__init__.py +0 -55
  185. sqlspec/builder/mixins/_cte_and_set_ops.py +0 -254
  186. sqlspec/builder/mixins/_delete_operations.py +0 -50
  187. sqlspec/builder/mixins/_insert_operations.py +0 -282
  188. sqlspec/builder/mixins/_join_operations.py +0 -389
  189. sqlspec/builder/mixins/_merge_operations.py +0 -592
  190. sqlspec/builder/mixins/_order_limit_operations.py +0 -152
  191. sqlspec/builder/mixins/_pivot_operations.py +0 -157
  192. sqlspec/builder/mixins/_select_operations.py +0 -936
  193. sqlspec/builder/mixins/_update_operations.py +0 -218
  194. sqlspec/builder/mixins/_where_clause.py +0 -1304
  195. sqlspec-0.25.0.dist-info/RECORD +0 -139
  196. sqlspec-0.25.0.dist-info/licenses/NOTICE +0 -29
  197. {sqlspec-0.25.0.dist-info → sqlspec-0.27.0.dist-info}/WHEEL +0 -0
  198. {sqlspec-0.25.0.dist-info → sqlspec-0.27.0.dist-info}/entry_points.txt +0 -0
  199. {sqlspec-0.25.0.dist-info → sqlspec-0.27.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,218 +0,0 @@
1
- # pyright: reportPrivateUsage=false
2
- """UPDATE operation mixins.
3
-
4
- Provides mixins for UPDATE statement functionality including
5
- table specification, SET clauses, and FROM clauses.
6
- """
7
-
8
- from collections.abc import Mapping
9
- from typing import Any, Optional, Union, cast
10
-
11
- from mypy_extensions import trait
12
- from sqlglot import exp
13
- from typing_extensions import Self
14
-
15
- from sqlspec.exceptions import SQLBuilderError
16
- from sqlspec.utils.type_guards import has_query_builder_parameters
17
-
18
- __all__ = ("UpdateFromClauseMixin", "UpdateSetClauseMixin", "UpdateTableClauseMixin")
19
-
20
- MIN_SET_ARGS = 2
21
-
22
-
23
- @trait
24
- class UpdateTableClauseMixin:
25
- """Mixin providing TABLE clause for UPDATE builders."""
26
-
27
- __slots__ = ()
28
-
29
- # Type annotations for PyRight - these will be provided by the base class
30
- def get_expression(self) -> Optional[exp.Expression]: ...
31
- def set_expression(self, expression: exp.Expression) -> None: ...
32
-
33
- def table(self, table_name: str, alias: Optional[str] = None) -> Self:
34
- """Set the table to update.
35
-
36
- Args:
37
- table_name: The name of the table.
38
- alias: Optional alias for the table.
39
-
40
- Returns:
41
- The current builder instance for method chaining.
42
- """
43
- current_expr = self.get_expression()
44
- if current_expr is None or not isinstance(current_expr, exp.Update):
45
- self.set_expression(exp.Update(this=None, expressions=[], joins=[]))
46
- current_expr = self.get_expression()
47
-
48
- assert current_expr is not None
49
- table_expr: exp.Expression = exp.to_table(table_name, alias=alias)
50
- current_expr.set("this", table_expr)
51
- setattr(self, "_table", table_name)
52
- return self
53
-
54
-
55
- @trait
56
- class UpdateSetClauseMixin:
57
- """Mixin providing SET clause for UPDATE builders."""
58
-
59
- __slots__ = ()
60
-
61
- # Type annotations for PyRight - these will be provided by the base class
62
- def get_expression(self) -> Optional[exp.Expression]: ...
63
- def set_expression(self, expression: exp.Expression) -> None: ...
64
-
65
- def add_parameter(self, value: Any, name: Optional[str] = None) -> tuple[Any, str]:
66
- """Add parameter - provided by QueryBuilder."""
67
- msg = "Method must be provided by QueryBuilder subclass"
68
- raise NotImplementedError(msg)
69
-
70
- def _generate_unique_parameter_name(self, base_name: str) -> str:
71
- """Generate unique parameter name - provided by QueryBuilder."""
72
- msg = "Method must be provided by QueryBuilder subclass"
73
- raise NotImplementedError(msg)
74
-
75
- def _process_update_value(self, val: Any, col: Any) -> exp.Expression:
76
- """Process a value for UPDATE assignment, handling SQL objects and parameters.
77
-
78
- Args:
79
- val: The value to process
80
- col: The column name for parameter naming
81
-
82
- Returns:
83
- The processed expression for the value
84
- """
85
- if isinstance(val, exp.Expression):
86
- return val
87
- if has_query_builder_parameters(val):
88
- subquery = val.build()
89
- sql_str = subquery.sql if hasattr(subquery, "sql") and not callable(subquery.sql) else str(subquery)
90
- value_expr = exp.paren(exp.maybe_parse(sql_str, dialect=getattr(self, "dialect", None)))
91
- if has_query_builder_parameters(val):
92
- for p_name, p_value in val.parameters.items():
93
- self.add_parameter(p_value, name=p_name)
94
- return value_expr
95
- if hasattr(val, "expression") and hasattr(val, "sql"):
96
- # Handle SQL objects (from sql.raw with parameters)
97
- expression = getattr(val, "expression", None)
98
- if expression is not None and isinstance(expression, exp.Expression):
99
- # Merge parameters from SQL object into builder
100
- if hasattr(val, "parameters"):
101
- sql_parameters = getattr(val, "parameters", {})
102
- for param_name, param_value in sql_parameters.items():
103
- self.add_parameter(param_value, name=param_name)
104
- return cast("exp.Expression", expression)
105
- # If expression is None, fall back to parsing the raw SQL
106
- sql_text = getattr(val, "sql", "")
107
- # Merge parameters even when parsing raw SQL
108
- if hasattr(val, "parameters"):
109
- sql_parameters = getattr(val, "parameters", {})
110
- for param_name, param_value in sql_parameters.items():
111
- self.add_parameter(param_value, name=param_name)
112
- parsed_expr = exp.maybe_parse(sql_text)
113
- return parsed_expr if parsed_expr is not None else exp.convert(str(sql_text))
114
- column_name = col if isinstance(col, str) else str(col)
115
- if "." in column_name:
116
- column_name = column_name.split(".")[-1]
117
- param_name = self._generate_unique_parameter_name(column_name)
118
- param_name = self.add_parameter(val, name=param_name)[1]
119
- return exp.Placeholder(this=param_name)
120
-
121
- def set(self, *args: Any, **kwargs: Any) -> Self:
122
- """Set columns and values for the UPDATE statement.
123
-
124
- Supports:
125
- - set_(column, value)
126
- - set_(mapping)
127
- - set_(**kwargs)
128
- - set_(mapping, **kwargs)
129
-
130
- Args:
131
- *args: Either (column, value) or a mapping.
132
- **kwargs: Column-value pairs to set.
133
-
134
- Raises:
135
- SQLBuilderError: If the current expression is not an UPDATE statement or usage is invalid.
136
-
137
- Returns:
138
- The current builder instance for method chaining.
139
- """
140
- current_expr = self.get_expression()
141
- if current_expr is None:
142
- self.set_expression(exp.Update())
143
- current_expr = self.get_expression()
144
-
145
- if not isinstance(current_expr, exp.Update):
146
- msg = "Cannot add SET clause to non-UPDATE expression."
147
- raise SQLBuilderError(msg)
148
- assignments = []
149
- if len(args) == MIN_SET_ARGS and not kwargs:
150
- col, val = args
151
- col_expr = col if isinstance(col, exp.Column) else exp.column(col)
152
- value_expr = self._process_update_value(val, col)
153
- assignments.append(exp.EQ(this=col_expr, expression=value_expr))
154
- elif (len(args) == 1 and isinstance(args[0], Mapping)) or kwargs:
155
- all_values = dict(args[0] if args else {}, **kwargs)
156
- for col, val in all_values.items():
157
- value_expr = self._process_update_value(val, col)
158
- assignments.append(exp.EQ(this=exp.column(col), expression=value_expr))
159
- else:
160
- msg = "Invalid arguments for set(): use (column, value), mapping, or kwargs."
161
- raise SQLBuilderError(msg)
162
- existing = current_expr.args.get("expressions", [])
163
- current_expr.set("expressions", existing + assignments)
164
- return self
165
-
166
-
167
- @trait
168
- class UpdateFromClauseMixin:
169
- """Mixin providing FROM clause for UPDATE builders (e.g., PostgreSQL style)."""
170
-
171
- __slots__ = ()
172
-
173
- # Type annotations for PyRight - these will be provided by the base class
174
- def get_expression(self) -> Optional[exp.Expression]: ...
175
- def set_expression(self, expression: exp.Expression) -> None: ...
176
-
177
- def from_(self, table: Union[str, exp.Expression, Any], alias: Optional[str] = None) -> Self:
178
- """Add a FROM clause to the UPDATE statement.
179
-
180
- Args:
181
- table: The table name, expression, or subquery to add to the FROM clause.
182
- alias: Optional alias for the table in the FROM clause.
183
-
184
- Returns:
185
- The current builder instance for method chaining.
186
-
187
- Raises:
188
- SQLBuilderError: If the current expression is not an UPDATE statement.
189
- """
190
- current_expr = self.get_expression()
191
- if current_expr is None or not isinstance(current_expr, exp.Update):
192
- msg = "Cannot add FROM clause to non-UPDATE expression. Set the main table first."
193
- raise SQLBuilderError(msg)
194
- table_expr: exp.Expression
195
- if isinstance(table, str):
196
- table_expr = exp.to_table(table, alias=alias)
197
- elif has_query_builder_parameters(table):
198
- subquery_builder_parameters = getattr(table, "_parameters", None)
199
- if subquery_builder_parameters:
200
- for p_name, p_value in subquery_builder_parameters.items():
201
- self.add_parameter(p_value, name=p_name) # type: ignore[attr-defined]
202
- subquery_exp = exp.paren(getattr(table, "_expression", exp.select()))
203
- table_expr = exp.alias_(subquery_exp, alias) if alias else subquery_exp
204
- elif isinstance(table, exp.Expression):
205
- table_expr = exp.alias_(table, alias) if alias else table
206
- else:
207
- msg = f"Unsupported table type for FROM clause: {type(table)}"
208
- raise SQLBuilderError(msg)
209
- if current_expr.args.get("from") is None:
210
- current_expr.set("from", exp.From(expressions=[]))
211
- from_clause = current_expr.args["from"]
212
- if hasattr(from_clause, "append"):
213
- from_clause.append("expressions", table_expr)
214
- else:
215
- if not from_clause.expressions:
216
- from_clause.expressions = []
217
- from_clause.expressions.append(table_expr)
218
- return self