sqlspec 0.19.0__py3-none-any.whl → 0.21.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 +11 -11
  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/config.py +15 -15
  33. sqlspec/core/compiler.py +11 -3
  34. sqlspec/core/filters.py +30 -9
  35. sqlspec/core/parameters.py +67 -67
  36. sqlspec/core/result.py +62 -31
  37. sqlspec/core/splitter.py +160 -34
  38. sqlspec/core/statement.py +95 -14
  39. sqlspec/driver/_common.py +12 -3
  40. sqlspec/driver/mixins/_result_tools.py +21 -4
  41. sqlspec/driver/mixins/_sql_translator.py +45 -7
  42. sqlspec/extensions/aiosql/adapter.py +1 -1
  43. sqlspec/extensions/litestar/_utils.py +1 -1
  44. sqlspec/extensions/litestar/config.py +186 -2
  45. sqlspec/extensions/litestar/handlers.py +21 -0
  46. sqlspec/extensions/litestar/plugin.py +237 -3
  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.19.0.dist-info → sqlspec-0.21.0.dist-info}/METADATA +230 -44
  60. {sqlspec-0.19.0.dist-info → sqlspec-0.21.0.dist-info}/RECORD +64 -64
  61. {sqlspec-0.19.0.dist-info → sqlspec-0.21.0.dist-info}/WHEEL +0 -0
  62. {sqlspec-0.19.0.dist-info → sqlspec-0.21.0.dist-info}/entry_points.txt +0 -0
  63. {sqlspec-0.19.0.dist-info → sqlspec-0.21.0.dist-info}/licenses/LICENSE +0 -0
  64. {sqlspec-0.19.0.dist-info → sqlspec-0.21.0.dist-info}/licenses/NOTICE +0 -0
@@ -1,7 +1,7 @@
1
- """Centralized parsing utilities for SQLSpec builders.
1
+ """Parsing utilities for SQL builders.
2
2
 
3
- This module provides common parsing functions to handle complex SQL expressions
4
- that users might pass as strings to various builder methods.
3
+ Provides common parsing functions to handle SQL expressions
4
+ passed as strings to builder methods.
5
5
  """
6
6
 
7
7
  import contextlib
@@ -1,7 +1,7 @@
1
- """Safe SQL query builder with validation and parameter binding.
1
+ """SELECT statement builder.
2
2
 
3
- This module provides a fluent interface for building SQL queries safely,
4
- with automatic parameter binding and validation.
3
+ Provides a fluent interface for building SQL SELECT queries with
4
+ parameter binding and validation.
5
5
  """
6
6
 
7
7
  import re
@@ -44,9 +44,10 @@ class Select(
44
44
  PivotClauseMixin,
45
45
  UnpivotClauseMixin,
46
46
  ):
47
- """Type-safe builder for SELECT queries with schema/model integration.
47
+ """Builder for SELECT queries.
48
48
 
49
- This builder provides a fluent, safe interface for constructing SQL SELECT statements.
49
+ Provides a fluent interface for constructing SQL SELECT statements
50
+ with parameter binding and validation.
50
51
 
51
52
  Example:
52
53
  >>> class User(BaseModel):
@@ -1,7 +1,7 @@
1
- """Safe SQL query builder with validation and parameter binding.
1
+ """UPDATE statement builder.
2
2
 
3
- This module provides a fluent interface for building SQL queries safely,
4
- with automatic parameter binding and validation.
3
+ Provides a fluent interface for building SQL UPDATE queries with
4
+ parameter binding and validation.
5
5
  """
6
6
 
7
7
  from typing import TYPE_CHECKING, Any, Optional, Union
@@ -36,8 +36,7 @@ class Update(
36
36
  ):
37
37
  """Builder for UPDATE statements.
38
38
 
39
- This builder provides a fluent interface for constructing SQL UPDATE statements
40
- with automatic parameter binding and validation.
39
+ Constructs SQL UPDATE statements with parameter binding and validation.
41
40
 
42
41
  Example:
43
42
  ```python
@@ -1,4 +1,8 @@
1
- """CTE (Common Table Expression) and Set Operations mixins for SQL builders."""
1
+ """CTE and set operation mixins.
2
+
3
+ Provides mixins for Common Table Expressions (WITH clause) and
4
+ set operations (UNION, INTERSECT, EXCEPT).
5
+ """
2
6
 
3
7
  from typing import Any, Optional, Union
4
8
 
@@ -1,4 +1,8 @@
1
- """Delete operation mixins for SQL builders."""
1
+ """DELETE operation mixins.
2
+
3
+ Provides mixins for DELETE statement functionality including
4
+ FROM clause specification.
5
+ """
2
6
 
3
7
  from typing import Optional
4
8
 
@@ -1,4 +1,8 @@
1
- """Insert operation mixins for SQL builders."""
1
+ """INSERT operation mixins.
2
+
3
+ Provides mixins for INSERT statement functionality including
4
+ INTO clauses, VALUES clauses, and INSERT FROM SELECT operations.
5
+ """
2
6
 
3
7
  from collections.abc import Sequence
4
8
  from typing import Any, Optional, TypeVar, Union
@@ -1,3 +1,8 @@
1
+ """JOIN operation mixins.
2
+
3
+ Provides mixins for JOIN operations in SELECT statements.
4
+ """
5
+
1
6
  from typing import TYPE_CHECKING, Any, Optional, Union, cast
2
7
 
3
8
  from mypy_extensions import trait
@@ -1,4 +1,8 @@
1
- """Merge operation mixins for SQL builders."""
1
+ """MERGE operation mixins.
2
+
3
+ Provides mixins for MERGE statement functionality including INTO,
4
+ USING, ON, WHEN MATCHED, and WHEN NOT MATCHED clauses.
5
+ """
2
6
 
3
7
  from typing import Any, Optional, Union
4
8
 
@@ -1,4 +1,8 @@
1
- """Order, Limit, Offset and Returning operations mixins for SQL builders."""
1
+ """ORDER BY, LIMIT, OFFSET, and RETURNING clause mixins.
2
+
3
+ Provides mixins for query result ordering, limiting, and result
4
+ returning functionality.
5
+ """
2
6
 
3
7
  from typing import TYPE_CHECKING, Optional, Union, cast
4
8
 
@@ -1,4 +1,7 @@
1
- """Pivot and Unpivot operations mixins for SQL builders."""
1
+ """PIVOT and UNPIVOT operation mixins.
2
+
3
+ Provides mixins for PIVOT and UNPIVOT operations in SELECT statements.
4
+ """
2
5
 
3
6
  from typing import TYPE_CHECKING, Optional, Union, cast
4
7
 
@@ -1,4 +1,8 @@
1
- """SELECT clause mixins consolidated into a single module."""
1
+ """SELECT clause mixins.
2
+
3
+ Provides mixins for SELECT statement functionality including column selection,
4
+ CASE expressions, subqueries, and window functions.
5
+ """
2
6
 
3
7
  from typing import TYPE_CHECKING, Any, Optional, Union, cast
4
8
 
@@ -1,4 +1,8 @@
1
- """Update operation mixins for SQL builders."""
1
+ """UPDATE operation mixins.
2
+
3
+ Provides mixins for UPDATE statement functionality including
4
+ table specification, SET clauses, and FROM clauses.
5
+ """
2
6
 
3
7
  from collections.abc import Mapping
4
8
  from typing import Any, Optional, Union, cast
@@ -1,5 +1,9 @@
1
1
  # ruff: noqa: PLR2004
2
- """Consolidated WHERE and HAVING clause mixins."""
2
+ """WHERE and HAVING clause mixins.
3
+
4
+ Provides mixins for WHERE and HAVING clause functionality with
5
+ parameter binding and various condition operators.
6
+ """
3
7
 
4
8
  from typing import TYPE_CHECKING, Any, Optional, Union, cast
5
9
 
sqlspec/config.py CHANGED
@@ -48,7 +48,7 @@ logger = get_logger("config")
48
48
 
49
49
 
50
50
  class LifecycleConfig(TypedDict, total=False):
51
- """Lifecycle hooks for all adapters.
51
+ """Lifecycle hooks for database adapters.
52
52
 
53
53
  Each hook accepts a list of callables to support multiple handlers.
54
54
  """
@@ -67,7 +67,7 @@ class LifecycleConfig(TypedDict, total=False):
67
67
  class MigrationConfig(TypedDict, total=False):
68
68
  """Configuration options for database migrations.
69
69
 
70
- All fields are optional with sensible defaults.
70
+ All fields are optional with default values.
71
71
  """
72
72
 
73
73
  script_location: NotRequired[str]
@@ -160,9 +160,9 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
160
160
  def get_signature_namespace(self) -> "dict[str, type[Any]]":
161
161
  """Get the signature namespace for this database configuration.
162
162
 
163
- This method returns a dictionary of type names to types that should be
164
- registered with Litestar's signature namespace to prevent serialization
165
- attempts on database-specific types.
163
+ Returns a dictionary of type names to types that should be registered
164
+ with Litestar's signature namespace to prevent serialization attempts
165
+ on database-specific types.
166
166
 
167
167
  Returns:
168
168
  Dictionary mapping type names to types.
@@ -172,8 +172,8 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
172
172
  def _initialize_migration_components(self) -> None:
173
173
  """Initialize migration loader and commands with necessary imports.
174
174
 
175
- This method handles the circular import between config and commands
176
- by importing at runtime when needed.
175
+ Handles the circular import between config and commands by importing
176
+ at runtime when needed.
177
177
  """
178
178
  from sqlspec.loader import SQLFileLoader
179
179
  from sqlspec.migrations.commands import MigrationCommands
@@ -185,7 +185,7 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
185
185
  """Get the migration SQL loader and auto-load files if needed.
186
186
 
187
187
  Returns:
188
- The SQLFileLoader instance for migration files.
188
+ SQLFileLoader instance for migration files.
189
189
  """
190
190
  # Auto-load migration files from configured migration path if it exists
191
191
  migration_config = self.migration_config or {}
@@ -204,14 +204,14 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
204
204
  """Get the migration commands instance.
205
205
 
206
206
  Returns:
207
- The MigrationCommands instance for this config.
207
+ MigrationCommands instance for this config.
208
208
  """
209
209
  return self._migration_commands
210
210
 
211
211
  def get_migration_loader(self) -> "SQLFileLoader":
212
212
  """Get the SQL loader for migration files.
213
213
 
214
- This provides access to migration SQL files loaded from the configured
214
+ Provides access to migration SQL files loaded from the configured
215
215
  script_location directory. Files are loaded lazily on first access.
216
216
 
217
217
  Returns:
@@ -269,7 +269,7 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
269
269
  verbose: Whether to show detailed migration history.
270
270
 
271
271
  Returns:
272
- The current migration version or None if no migrations applied.
272
+ Current migration version or None if no migrations applied.
273
273
  """
274
274
  commands = self._ensure_migration_commands()
275
275
  return commands.current(verbose=verbose)
@@ -301,7 +301,7 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
301
301
 
302
302
 
303
303
  class NoPoolSyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
304
- """Base class for a sync database configurations that do not implement a pool."""
304
+ """Base class for sync database configurations that do not implement a pool."""
305
305
 
306
306
  __slots__ = ("connection_config",)
307
307
  is_async: "ClassVar[bool]" = False
@@ -355,7 +355,7 @@ class NoPoolSyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
355
355
 
356
356
 
357
357
  class NoPoolAsyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
358
- """Base class for an async database configurations that do not implement a pool."""
358
+ """Base class for async database configurations that do not implement a pool."""
359
359
 
360
360
  __slots__ = ("connection_config",)
361
361
  is_async: "ClassVar[bool]" = True
@@ -409,7 +409,7 @@ class NoPoolAsyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
409
409
 
410
410
 
411
411
  class SyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
412
- """Generic Sync Database Configuration."""
412
+ """Base class for sync database configurations with connection pooling."""
413
413
 
414
414
  __slots__ = ("pool_config",)
415
415
  is_async: "ClassVar[bool]" = False
@@ -486,7 +486,7 @@ class SyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
486
486
 
487
487
 
488
488
  class AsyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
489
- """Generic Async Database Configuration."""
489
+ """Base class for async database configurations with connection pooling."""
490
490
 
491
491
  __slots__ = ("pool_config",)
492
492
  is_async: "ClassVar[bool]" = True
sqlspec/core/compiler.py CHANGED
@@ -17,6 +17,7 @@ from sqlglot.errors import ParseError
17
17
  from typing_extensions import Literal
18
18
 
19
19
  from sqlspec.core.parameters import ParameterProcessor
20
+ from sqlspec.exceptions import SQLSpecError
20
21
  from sqlspec.utils.logging import get_logger
21
22
 
22
23
  if TYPE_CHECKING:
@@ -61,6 +62,8 @@ class CompiledSQL:
61
62
  """Compiled SQL result.
62
63
 
63
64
  Contains the result of SQL compilation with information needed for execution.
65
+ Immutable container holding compiled SQL text, processed parameters, operation
66
+ type, and execution metadata.
64
67
  """
65
68
 
66
69
  __slots__ = (
@@ -133,7 +136,9 @@ class CompiledSQL:
133
136
  class SQLProcessor:
134
137
  """SQL processor with compilation and caching.
135
138
 
136
- Processes SQL statements with parameter processing and caching.
139
+ Processes SQL statements by compiling them into executable format with
140
+ parameter substitution. Includes LRU-style caching for compilation results
141
+ to avoid re-processing identical statements.
137
142
  """
138
143
 
139
144
  __slots__ = ("_cache", "_cache_hits", "_cache_misses", "_config", "_max_cache_size", "_parameter_processor")
@@ -157,7 +162,7 @@ class SQLProcessor:
157
162
 
158
163
  Args:
159
164
  sql: SQL string for compilation
160
- parameters: Parameter values
165
+ parameters: Parameter values for substitution
161
166
  is_many: Whether this is for execute_many operation
162
167
 
163
168
  Returns:
@@ -261,6 +266,9 @@ class SQLProcessor:
261
266
  supports_many=isinstance(final_params, list) and len(final_params) > 0,
262
267
  )
263
268
 
269
+ except SQLSpecError:
270
+ # Re-raise SQLSpecError (validation errors, parameter mismatches) - these should fail hard
271
+ raise
264
272
  except Exception as e:
265
273
  logger.warning("Compilation failed, using fallback: %s", e)
266
274
  return CompiledSQL(compiled_sql=sql, execution_parameters=parameters, operation_type="UNKNOWN")
@@ -340,7 +348,7 @@ class SQLProcessor:
340
348
  return sql, parameters
341
349
 
342
350
  def clear_cache(self) -> None:
343
- """Clear cache."""
351
+ """Clear compilation cache and reset statistics."""
344
352
  self._cache.clear()
345
353
  self._cache_hits = 0
346
354
  self._cache_misses = 0
sqlspec/core/filters.py CHANGED
@@ -196,7 +196,10 @@ class BeforeAfterFilter(StatementFilter):
196
196
 
197
197
 
198
198
  class OnBeforeAfterFilter(StatementFilter):
199
- """Data required to filter a query on a ``datetime`` column."""
199
+ """Filter for inclusive datetime range queries.
200
+
201
+ Applies WHERE clauses for on-or-before/on-or-after datetime filtering.
202
+ """
200
203
 
201
204
  __slots__ = ("_param_name_on_or_after", "_param_name_on_or_before", "field_name", "on_or_after", "on_or_before")
202
205
 
@@ -277,7 +280,7 @@ class OnBeforeAfterFilter(StatementFilter):
277
280
 
278
281
 
279
282
  class InAnyFilter(StatementFilter, ABC, Generic[T]):
280
- """Subclass for methods that have a `prefer_any` attribute."""
283
+ """Base class for collection-based filters that support ANY operations."""
281
284
 
282
285
  __slots__ = ()
283
286
 
@@ -346,7 +349,10 @@ class InCollectionFilter(InAnyFilter[T]):
346
349
 
347
350
 
348
351
  class NotInCollectionFilter(InAnyFilter[T]):
349
- """Data required to construct a ``WHERE ... NOT IN (...)`` clause."""
352
+ """Filter for NOT IN clause queries.
353
+
354
+ Constructs WHERE ... NOT IN (...) clauses.
355
+ """
350
356
 
351
357
  __slots__ = ("_param_names", "field_name", "values")
352
358
 
@@ -401,7 +407,10 @@ class NotInCollectionFilter(InAnyFilter[T]):
401
407
 
402
408
 
403
409
  class AnyCollectionFilter(InAnyFilter[T]):
404
- """Data required to construct a ``WHERE column_name = ANY (array_expression)`` clause."""
410
+ """Filter for PostgreSQL-style ANY clause queries.
411
+
412
+ Constructs WHERE column_name = ANY (array_expression) clauses.
413
+ """
405
414
 
406
415
  __slots__ = ("_param_names", "field_name", "values")
407
416
 
@@ -460,7 +469,10 @@ class AnyCollectionFilter(InAnyFilter[T]):
460
469
 
461
470
 
462
471
  class NotAnyCollectionFilter(InAnyFilter[T]):
463
- """Data required to construct a ``WHERE NOT (column_name = ANY (array_expression))`` clause."""
472
+ """Filter for PostgreSQL-style NOT ANY clause queries.
473
+
474
+ Constructs WHERE NOT (column_name = ANY (array_expression)) clauses.
475
+ """
464
476
 
465
477
  __slots__ = ("_param_names", "field_name", "values")
466
478
 
@@ -514,7 +526,7 @@ class NotAnyCollectionFilter(InAnyFilter[T]):
514
526
 
515
527
 
516
528
  class PaginationFilter(StatementFilter, ABC):
517
- """Subclass for methods that function as a pagination type."""
529
+ """Base class for pagination-related filters."""
518
530
 
519
531
  __slots__ = ()
520
532
 
@@ -524,7 +536,10 @@ class PaginationFilter(StatementFilter, ABC):
524
536
 
525
537
 
526
538
  class LimitOffsetFilter(PaginationFilter):
527
- """Data required to add limit/offset filtering to a query."""
539
+ """Filter for LIMIT and OFFSET clauses.
540
+
541
+ Adds pagination support through LIMIT/OFFSET SQL clauses.
542
+ """
528
543
 
529
544
  __slots__ = ("_limit_param_name", "_offset_param_name", "limit", "offset")
530
545
 
@@ -576,7 +591,10 @@ class LimitOffsetFilter(PaginationFilter):
576
591
 
577
592
 
578
593
  class OrderByFilter(StatementFilter):
579
- """Data required to construct a ``ORDER BY ...`` clause."""
594
+ """Filter for ORDER BY clauses.
595
+
596
+ Adds sorting capability to SQL queries.
597
+ """
580
598
 
581
599
  __slots__ = ("field_name", "sort_order")
582
600
 
@@ -694,7 +712,10 @@ class SearchFilter(StatementFilter):
694
712
 
695
713
 
696
714
  class NotInSearchFilter(SearchFilter):
697
- """Data required to construct a ``WHERE field_name NOT LIKE '%' || :value || '%'`` clause."""
715
+ """Filter for negated text search queries.
716
+
717
+ Constructs WHERE field_name NOT LIKE '%value%' clauses.
718
+ """
698
719
 
699
720
  __slots__ = ()
700
721