sqlspec 0.18.0__py3-none-any.whl → 0.20.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 (64) hide show
  1. sqlspec/adapters/adbc/driver.py +192 -28
  2. sqlspec/adapters/asyncmy/driver.py +72 -15
  3. sqlspec/adapters/asyncpg/config.py +23 -3
  4. sqlspec/adapters/asyncpg/driver.py +30 -14
  5. sqlspec/adapters/bigquery/driver.py +79 -9
  6. sqlspec/adapters/duckdb/driver.py +39 -56
  7. sqlspec/adapters/oracledb/driver.py +99 -52
  8. sqlspec/adapters/psqlpy/driver.py +89 -31
  9. sqlspec/adapters/psycopg/driver.py +11 -23
  10. sqlspec/adapters/sqlite/driver.py +77 -8
  11. sqlspec/base.py +29 -25
  12. sqlspec/builder/__init__.py +1 -1
  13. sqlspec/builder/_base.py +4 -5
  14. sqlspec/builder/_column.py +3 -3
  15. sqlspec/builder/_ddl.py +5 -1
  16. sqlspec/builder/_delete.py +5 -6
  17. sqlspec/builder/_insert.py +6 -7
  18. sqlspec/builder/_merge.py +5 -5
  19. sqlspec/builder/_parsing_utils.py +3 -3
  20. sqlspec/builder/_select.py +6 -5
  21. sqlspec/builder/_update.py +4 -5
  22. sqlspec/builder/mixins/_cte_and_set_ops.py +5 -1
  23. sqlspec/builder/mixins/_delete_operations.py +5 -1
  24. sqlspec/builder/mixins/_insert_operations.py +5 -1
  25. sqlspec/builder/mixins/_join_operations.py +5 -0
  26. sqlspec/builder/mixins/_merge_operations.py +5 -1
  27. sqlspec/builder/mixins/_order_limit_operations.py +5 -1
  28. sqlspec/builder/mixins/_pivot_operations.py +4 -1
  29. sqlspec/builder/mixins/_select_operations.py +5 -1
  30. sqlspec/builder/mixins/_update_operations.py +5 -1
  31. sqlspec/builder/mixins/_where_clause.py +5 -1
  32. sqlspec/cli.py +281 -33
  33. sqlspec/config.py +160 -10
  34. sqlspec/core/compiler.py +11 -3
  35. sqlspec/core/filters.py +30 -9
  36. sqlspec/core/parameters.py +67 -67
  37. sqlspec/core/result.py +62 -31
  38. sqlspec/core/splitter.py +160 -34
  39. sqlspec/core/statement.py +95 -14
  40. sqlspec/driver/_common.py +12 -3
  41. sqlspec/driver/mixins/_result_tools.py +21 -4
  42. sqlspec/driver/mixins/_sql_translator.py +45 -7
  43. sqlspec/extensions/aiosql/adapter.py +1 -1
  44. sqlspec/extensions/litestar/_utils.py +1 -1
  45. sqlspec/extensions/litestar/handlers.py +21 -0
  46. sqlspec/extensions/litestar/plugin.py +15 -8
  47. sqlspec/loader.py +12 -12
  48. sqlspec/migrations/loaders.py +5 -2
  49. sqlspec/migrations/utils.py +2 -2
  50. sqlspec/storage/backends/obstore.py +1 -3
  51. sqlspec/storage/registry.py +1 -1
  52. sqlspec/utils/__init__.py +7 -0
  53. sqlspec/utils/deprecation.py +6 -0
  54. sqlspec/utils/fixtures.py +239 -30
  55. sqlspec/utils/module_loader.py +5 -1
  56. sqlspec/utils/serializers.py +6 -0
  57. sqlspec/utils/singleton.py +6 -0
  58. sqlspec/utils/sync_tools.py +10 -1
  59. {sqlspec-0.18.0.dist-info → sqlspec-0.20.0.dist-info}/METADATA +1 -1
  60. {sqlspec-0.18.0.dist-info → sqlspec-0.20.0.dist-info}/RECORD +64 -64
  61. {sqlspec-0.18.0.dist-info → sqlspec-0.20.0.dist-info}/WHEEL +0 -0
  62. {sqlspec-0.18.0.dist-info → sqlspec-0.20.0.dist-info}/entry_points.txt +0 -0
  63. {sqlspec-0.18.0.dist-info → sqlspec-0.20.0.dist-info}/licenses/LICENSE +0 -0
  64. {sqlspec-0.18.0.dist-info → sqlspec-0.20.0.dist-info}/licenses/NOTICE +0 -0
@@ -12,7 +12,7 @@ Components:
12
12
  - ParameterProcessor: Parameter processing coordinator
13
13
  - ParameterStyleConfig: Configuration for parameter processing
14
14
 
15
- Features:
15
+ Processing:
16
16
  - Two-phase processing: compatibility and execution format
17
17
  - Type-specific parameter wrapping
18
18
  - Parameter style conversions
@@ -99,12 +99,10 @@ class TypedParameter:
99
99
  Maintains type information through parsing and execution
100
100
  format conversion.
101
101
 
102
- Use Cases:
103
- - Preserve boolean values through parsing
104
- - Maintain Decimal precision
105
- - Handle date/datetime formatting
106
- - Preserve array/list structures
107
- - Handle JSON serialization for dict parameters
102
+ Attributes:
103
+ value: The parameter value
104
+ original_type: The original Python type of the value
105
+ semantic_name: Optional name for debugging purposes
108
106
  """
109
107
 
110
108
  __slots__ = ("_hash", "original_type", "semantic_name", "value")
@@ -123,7 +121,7 @@ class TypedParameter:
123
121
  self._hash: Optional[int] = None
124
122
 
125
123
  def __hash__(self) -> int:
126
- """Cached hash value with optimization."""
124
+ """Cached hash value."""
127
125
  if self._hash is None:
128
126
  value_id = id(self.value)
129
127
  self._hash = hash((value_id, self.original_type, self.semantic_name))
@@ -193,12 +191,14 @@ def _(value: bytes, semantic_name: Optional[str] = None) -> TypedParameter:
193
191
  class ParameterInfo:
194
192
  """Information about a detected parameter in SQL.
195
193
 
196
- Tracks parameter metadata for conversion:
197
- - name: Parameter name (for named styles)
198
- - style: Parameter style
199
- - position: Character position in SQL string
200
- - ordinal: Order of appearance (0-indexed)
201
- - placeholder_text: Original text in SQL
194
+ Tracks parameter metadata for conversion operations.
195
+
196
+ Attributes:
197
+ name: Parameter name (for named styles)
198
+ style: Parameter style
199
+ position: Character position in SQL string
200
+ ordinal: Order of appearance (0-indexed)
201
+ placeholder_text: Original text in SQL
202
202
  """
203
203
 
204
204
  __slots__ = ("name", "ordinal", "placeholder_text", "position", "style")
@@ -234,15 +234,17 @@ class ParameterInfo:
234
234
  class ParameterStyleConfig:
235
235
  """Configuration for parameter style processing.
236
236
 
237
- Provides configuration for parameter processing including:
238
- - default_parameter_style: Primary parsing style
239
- - supported_parameter_styles: All input styles supported
240
- - supported_execution_parameter_styles: Styles driver can execute
241
- - default_execution_parameter_style: Target execution format
242
- - type_coercion_map: Type conversions
243
- - output_transformer: Final SQL/parameter transformation hook
244
- - preserve_parameter_format: Maintain original parameter structure
245
- - needs_static_script_compilation: Embed parameters in SQL
237
+ Provides configuration for parameter processing operations.
238
+
239
+ Attributes:
240
+ default_parameter_style: Primary parsing style
241
+ supported_parameter_styles: All input styles supported
242
+ supported_execution_parameter_styles: Styles driver can execute
243
+ default_execution_parameter_style: Target execution format
244
+ type_coercion_map: Type conversions
245
+ output_transformer: Final SQL/parameter transformation hook
246
+ preserve_parameter_format: Maintain original parameter structure
247
+ needs_static_script_compilation: Embed parameters in SQL
246
248
  """
247
249
 
248
250
  __slots__ = (
@@ -275,7 +277,7 @@ class ParameterStyleConfig:
275
277
  output_transformer: Optional[Callable[[str, Any], tuple[str, Any]]] = None,
276
278
  ast_transformer: Optional[Callable[[Any, Any], tuple[Any, Any]]] = None,
277
279
  ) -> None:
278
- """Initialize with complete compatibility.
280
+ """Initialize parameter style configuration.
279
281
 
280
282
  Args:
281
283
  default_parameter_style: Primary parameter style for parsing
@@ -289,7 +291,7 @@ class ParameterStyleConfig:
289
291
  allow_mixed_parameter_styles: Support mixed styles in single query
290
292
  preserve_parameter_format: Maintain original parameter structure
291
293
  preserve_original_params_for_many: Return original list of tuples for execute_many
292
- ast_transformer: AST-based transformation hook for advanced SQL/parameter manipulation
294
+ ast_transformer: AST-based transformation hook for SQL/parameter manipulation
293
295
  """
294
296
  self.default_parameter_style = default_parameter_style
295
297
  self.supported_parameter_styles = (
@@ -338,12 +340,7 @@ class ParameterValidator:
338
340
  """Parameter validation and extraction.
339
341
 
340
342
  Extracts parameter information from SQL strings and determines
341
- compatibility.
342
-
343
- Features:
344
- - Parameter extraction results
345
- - Regex-based parameter detection
346
- - Dialect-specific compatibility checking
343
+ compatibility with target dialects.
347
344
  """
348
345
 
349
346
  __slots__ = ("_parameter_cache",)
@@ -464,11 +461,6 @@ class ParameterConverter:
464
461
  Handles two-phase parameter processing:
465
462
  - Phase 1: Compatibility normalization
466
463
  - Phase 2: Execution format conversion
467
-
468
- Features:
469
- - Converts incompatible styles to canonical format
470
- - Enables parsing of problematic parameter styles
471
- - Handles parameter format changes (list ↔ dict, positional ↔ named)
472
464
  """
473
465
 
474
466
  __slots__ = ("_format_converters", "_placeholder_generators", "validator")
@@ -678,7 +670,7 @@ class ParameterConverter:
678
670
 
679
671
  return None, False
680
672
 
681
- def _extract_param_value_single_style(self, param: ParameterInfo, parameters: Mapping) -> Any:
673
+ def _extract_param_value_single_style(self, param: ParameterInfo, parameters: Mapping) -> "tuple[Any, bool]":
682
674
  """Extract parameter value for single style parameters.
683
675
 
684
676
  Args:
@@ -686,18 +678,18 @@ class ParameterConverter:
686
678
  parameters: Parameter mapping
687
679
 
688
680
  Returns:
689
- Parameter value or None if not found
681
+ Tuple of (value, found_flag) where found_flag indicates if parameter was found
690
682
  """
691
683
  if param.name and param.name in parameters:
692
- return parameters[param.name]
684
+ return parameters[param.name], True
693
685
  if f"param_{param.ordinal}" in parameters:
694
- return parameters[f"param_{param.ordinal}"]
686
+ return parameters[f"param_{param.ordinal}"], True
695
687
 
696
688
  ordinal_key = str(param.ordinal + 1)
697
689
  if ordinal_key in parameters:
698
- return parameters[ordinal_key]
690
+ return parameters[ordinal_key], True
699
691
 
700
- return None
692
+ return None, False
701
693
 
702
694
  def _preserve_original_format(self, param_values: "list[Any]", original_parameters: Any) -> Any:
703
695
  """Preserve the original parameter container format.
@@ -771,8 +763,8 @@ class ParameterConverter:
771
763
  param_values.append(value)
772
764
  else:
773
765
  for param in param_info:
774
- value = self._extract_param_value_single_style(param, parameters)
775
- if value is not None:
766
+ value, found = self._extract_param_value_single_style(param, parameters)
767
+ if found:
776
768
  param_values.append(value)
777
769
 
778
770
  if preserve_parameter_format and original_parameters is not None:
@@ -911,15 +903,15 @@ class ParameterConverter:
911
903
  class ParameterProcessor:
912
904
  """Parameter processing engine.
913
905
 
914
- This is the main entry point for the parameter processing system
915
- that coordinates Phase 1 (compatibility) and Phase 2 (execution format).
906
+ Main entry point for the parameter processing system that coordinates
907
+ Phase 1 (compatibility) and Phase 2 (execution format).
916
908
 
917
909
  Processing Pipeline:
918
- 1. Type wrapping for compatibility (TypedParameter)
919
- 2. Driver-specific type coercions (type_coercion_map)
920
- 3. Phase 1: Normalization if needed
921
- 4. Phase 2: Execution format conversion if needed
922
- 5. Final output transformation (output_transformer)
910
+ 1. Type wrapping for compatibility (TypedParameter)
911
+ 2. Driver-specific type coercions (type_coercion_map)
912
+ 3. Phase 1: Normalization if needed
913
+ 4. Phase 2: Execution format conversion if needed
914
+ 5. Final output transformation (output_transformer)
923
915
  """
924
916
 
925
917
  __slots__ = ("_cache", "_cache_size", "_converter", "_validator")
@@ -1001,14 +993,14 @@ class ParameterProcessor:
1001
993
  dialect: Optional[str] = None,
1002
994
  is_many: bool = False,
1003
995
  ) -> "tuple[str, Any]":
1004
- """Complete parameter processing pipeline.
996
+ """Process parameters through the complete pipeline.
1005
997
 
1006
- This method coordinates the entire parameter processing workflow:
1007
- 1. Type wrapping for compatibility
1008
- 2. Phase 1: Normalization if needed
1009
- 3. Phase 2: Execution format conversion
1010
- 4. Driver-specific type coercions
1011
- 5. Final output transformation
998
+ Coordinates the entire parameter processing workflow:
999
+ 1. Type wrapping for compatibility
1000
+ 2. Phase 1: Normalization if needed
1001
+ 3. Phase 2: Execution format conversion
1002
+ 4. Driver-specific type coercions
1003
+ 5. Final output transformation
1012
1004
 
1013
1005
  Args:
1014
1006
  sql: Raw SQL string
@@ -1077,7 +1069,7 @@ class ParameterProcessor:
1077
1069
  ) -> "tuple[str, Any]":
1078
1070
  """Get SQL normalized for parsing only (Phase 1 only).
1079
1071
 
1080
- This method performs only Phase 1 normalization to make SQL compatible
1072
+ Performs only Phase 1 normalization to make SQL compatible
1081
1073
  with parsing, without converting to execution format.
1082
1074
 
1083
1075
  Args:
@@ -1101,8 +1093,8 @@ class ParameterProcessor:
1101
1093
  def _needs_execution_conversion(self, param_info: "list[ParameterInfo]", config: ParameterStyleConfig) -> bool:
1102
1094
  """Determine if execution format conversion is needed.
1103
1095
 
1104
- Preserves the original parameter style if it's supported by the execution environment,
1105
- otherwise converts to the default execution style.
1096
+ Preserves the original parameter style if it's supported by the execution
1097
+ environment, otherwise converts to the default execution style.
1106
1098
  """
1107
1099
  if not param_info:
1108
1100
  return False
@@ -1141,11 +1133,11 @@ class ParameterProcessor:
1141
1133
  """Determine the target execution style based on original styles and config.
1142
1134
 
1143
1135
  Logic:
1144
- 1. If there's a single original style and it's in supported execution styles, use it
1145
- 2. Otherwise, use the default execution style
1146
- 3. If no default execution style, use the default parameter style
1136
+ 1. If there's a single original style and it's in supported execution styles, use it
1137
+ 2. Otherwise, use the default execution style
1138
+ 3. If no default execution style, use the default parameter style
1147
1139
 
1148
- This preserves the original parameter style when possible, only converting
1140
+ Preserves the original parameter style when possible, only converting
1149
1141
  when necessary for execution compatibility.
1150
1142
  """
1151
1143
 
@@ -1179,8 +1171,16 @@ class ParameterProcessor:
1179
1171
  """
1180
1172
 
1181
1173
  def coerce_value(value: Any) -> Any:
1174
+ # Skip coercion for None values to preserve NULL semantics
1175
+ if value is None:
1176
+ return value
1177
+
1182
1178
  if isinstance(value, TypedParameter):
1183
- wrapped_value = value.value
1179
+ wrapped_value: Any = value.value
1180
+ # Skip coercion for None values even when wrapped
1181
+ if wrapped_value is None:
1182
+ return wrapped_value
1183
+
1184
1184
  original_type = value.original_type
1185
1185
  if original_type in type_coercion_map:
1186
1186
  coerced = type_coercion_map[original_type](wrapped_value)
@@ -1236,7 +1236,7 @@ def is_iterable_parameters(obj: Any) -> bool:
1236
1236
 
1237
1237
 
1238
1238
  def wrap_with_type(value: Any, semantic_name: Optional[str] = None) -> Any:
1239
- """Public API for type wrapping - preserves current interface.
1239
+ """Public API for type wrapping.
1240
1240
 
1241
1241
  Args:
1242
1242
  value: Value to potentially wrap
sqlspec/core/result.py CHANGED
@@ -3,16 +3,10 @@
3
3
  This module provides result classes for handling SQL query execution results
4
4
  including regular results and Apache Arrow format results.
5
5
 
6
- Components:
7
- - StatementResult: Abstract base class for SQL results
8
- - SQLResult: Main implementation for regular results
9
- - ArrowResult: Arrow-based results for data interchange
10
-
11
- Features:
12
- - Consistent interface across all result types
13
- - Support for both regular and Arrow format results
14
- - Result metadata and statistics
15
- - Iterator support for result rows
6
+ Classes:
7
+ StatementResult: Abstract base class for SQL results.
8
+ SQLResult: Standard implementation for regular results.
9
+ ArrowResult: Apache Arrow format results for data interchange.
16
10
  """
17
11
 
18
12
  from abc import ABC, abstractmethod
@@ -36,17 +30,17 @@ T = TypeVar("T")
36
30
 
37
31
  @mypyc_attr(allow_interpreted_subclasses=False)
38
32
  class StatementResult(ABC):
39
- """Base class for SQL statement execution results.
33
+ """Abstract base class for SQL statement execution results.
40
34
 
41
35
  Provides a common interface for handling different types of SQL operation
42
- results. Subclasses implement specific behavior for SELECT, INSERT/UPDATE/DELETE,
43
- and script operations.
36
+ results. Subclasses implement specific behavior for SELECT, INSERT, UPDATE,
37
+ DELETE, and script operations.
44
38
 
45
- Args:
39
+ Attributes:
46
40
  statement: The original SQL statement that was executed.
47
- data: The result data from the operation (type varies by subclass).
48
- rows_affected: Number of rows affected by the operation (if applicable).
49
- last_inserted_id: Last inserted ID (if applicable).
41
+ data: The result data from the operation.
42
+ rows_affected: Number of rows affected by the operation.
43
+ last_inserted_id: Last inserted ID from INSERT operations.
50
44
  execution_time: Time taken to execute the statement in seconds.
51
45
  metadata: Additional metadata about the operation.
52
46
  """
@@ -131,10 +125,23 @@ class SQLResult(StatementResult):
131
125
  """Result class for SQL operations that return rows or affect rows.
132
126
 
133
127
  Handles SELECT, INSERT, UPDATE, DELETE operations. For DML operations with
134
- RETURNING clauses, the returned data will be in `self.data`. The `operation_type`
135
- attribute helps distinguish the nature of the operation.
136
-
137
- For script execution, this class also tracks multiple statement results and errors.
128
+ RETURNING clauses, the returned data is stored in the data attribute.
129
+ The operation_type attribute indicates the nature of the operation.
130
+
131
+ For script execution, tracks multiple statement results and errors.
132
+
133
+ Attributes:
134
+ column_names: Names of columns in the result set.
135
+ error: Exception that occurred during execution.
136
+ errors: List of error messages for script execution.
137
+ has_more: Whether there are additional result pages available.
138
+ inserted_ids: List of IDs from INSERT operations.
139
+ operation_index: Index of operation in a script.
140
+ parameters: Parameters used for the query.
141
+ statement_results: Results from individual statements in a script.
142
+ successful_statements: Count of successful statements in a script.
143
+ total_count: Total number of rows in the complete result set.
144
+ total_statements: Total number of statements in a script.
138
145
  """
139
146
 
140
147
  __slots__ = (
@@ -175,7 +182,28 @@ class SQLResult(StatementResult):
175
182
  total_statements: int = 0,
176
183
  successful_statements: int = 0,
177
184
  ) -> None:
178
- """Initialize SQL result."""
185
+ """Initialize SQL result.
186
+
187
+ Args:
188
+ statement: The original SQL statement that was executed.
189
+ data: The result data from the operation.
190
+ rows_affected: Number of rows affected by the operation.
191
+ last_inserted_id: Last inserted ID from the operation.
192
+ execution_time: Time taken to execute the statement in seconds.
193
+ metadata: Additional metadata about the operation.
194
+ error: Exception that occurred during execution.
195
+ operation_type: Type of SQL operation performed.
196
+ operation_index: Index of operation in a script.
197
+ parameters: Parameters used for the query.
198
+ column_names: Names of columns in the result set.
199
+ total_count: Total number of rows in the complete result set.
200
+ has_more: Whether there are additional result pages available.
201
+ inserted_ids: List of IDs from INSERT operations.
202
+ statement_results: Results from individual statements in a script.
203
+ errors: List of error messages for script execution.
204
+ total_statements: Total number of statements in a script.
205
+ successful_statements: Count of successful statements in a script.
206
+ """
179
207
  super().__init__(
180
208
  statement=statement,
181
209
  data=data,
@@ -205,7 +233,11 @@ class SQLResult(StatementResult):
205
233
 
206
234
  @property
207
235
  def operation_type(self) -> OperationType:
208
- """Get operation type for this result."""
236
+ """Get operation type for this result.
237
+
238
+ Returns:
239
+ The type of SQL operation that produced this result.
240
+ """
209
241
  return self._operation_type
210
242
 
211
243
  def get_metadata(self, key: str, default: Any = None) -> Any:
@@ -252,7 +284,8 @@ class SQLResult(StatementResult):
252
284
  """Get the data from the result.
253
285
 
254
286
  For regular operations, returns the list of rows.
255
- For script operations, returns a summary dictionary.
287
+ For script operations, returns a summary dictionary containing
288
+ execution statistics and results.
256
289
 
257
290
  Returns:
258
291
  List of result rows or script summary.
@@ -479,14 +512,12 @@ class SQLResult(StatementResult):
479
512
  class ArrowResult(StatementResult):
480
513
  """Result class for SQL operations that return Apache Arrow data.
481
514
 
482
- This class is used when database drivers support returning results as
483
- Apache Arrow format for data interchange, especially
484
- useful for analytics workloads and data science applications.
515
+ Used when database drivers support returning results in Apache Arrow
516
+ format for data interchange. Suitable for analytics workloads and
517
+ data science applications.
485
518
 
486
- Args:
487
- statement: The original SQL statement that was executed.
488
- data: The Apache Arrow Table containing the result data.
489
- schema: Optional Arrow schema information.
519
+ Attributes:
520
+ schema: Arrow schema information for the result data.
490
521
  """
491
522
 
492
523
  __slots__ = ("schema",)