sqlspec 0.17.1__py3-none-any.whl → 0.18.0__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (75) hide show
  1. sqlspec/__init__.py +1 -1
  2. sqlspec/_sql.py +54 -159
  3. sqlspec/adapters/adbc/config.py +24 -30
  4. sqlspec/adapters/adbc/driver.py +42 -61
  5. sqlspec/adapters/aiosqlite/config.py +5 -10
  6. sqlspec/adapters/aiosqlite/driver.py +9 -25
  7. sqlspec/adapters/aiosqlite/pool.py +43 -35
  8. sqlspec/adapters/asyncmy/config.py +10 -7
  9. sqlspec/adapters/asyncmy/driver.py +18 -39
  10. sqlspec/adapters/asyncpg/config.py +4 -0
  11. sqlspec/adapters/asyncpg/driver.py +32 -79
  12. sqlspec/adapters/bigquery/config.py +12 -65
  13. sqlspec/adapters/bigquery/driver.py +39 -133
  14. sqlspec/adapters/duckdb/config.py +11 -15
  15. sqlspec/adapters/duckdb/driver.py +61 -85
  16. sqlspec/adapters/duckdb/pool.py +2 -5
  17. sqlspec/adapters/oracledb/_types.py +8 -1
  18. sqlspec/adapters/oracledb/config.py +55 -38
  19. sqlspec/adapters/oracledb/driver.py +35 -92
  20. sqlspec/adapters/oracledb/migrations.py +257 -0
  21. sqlspec/adapters/psqlpy/config.py +13 -9
  22. sqlspec/adapters/psqlpy/driver.py +28 -103
  23. sqlspec/adapters/psycopg/config.py +9 -5
  24. sqlspec/adapters/psycopg/driver.py +107 -175
  25. sqlspec/adapters/sqlite/config.py +7 -5
  26. sqlspec/adapters/sqlite/driver.py +37 -73
  27. sqlspec/adapters/sqlite/pool.py +3 -12
  28. sqlspec/base.py +1 -8
  29. sqlspec/builder/__init__.py +1 -1
  30. sqlspec/builder/_base.py +34 -20
  31. sqlspec/builder/_ddl.py +407 -183
  32. sqlspec/builder/_insert.py +1 -1
  33. sqlspec/builder/mixins/_insert_operations.py +26 -6
  34. sqlspec/builder/mixins/_merge_operations.py +1 -1
  35. sqlspec/builder/mixins/_select_operations.py +1 -5
  36. sqlspec/config.py +32 -13
  37. sqlspec/core/__init__.py +89 -14
  38. sqlspec/core/cache.py +57 -104
  39. sqlspec/core/compiler.py +57 -112
  40. sqlspec/core/filters.py +1 -21
  41. sqlspec/core/hashing.py +13 -47
  42. sqlspec/core/parameters.py +272 -261
  43. sqlspec/core/result.py +12 -27
  44. sqlspec/core/splitter.py +17 -21
  45. sqlspec/core/statement.py +150 -159
  46. sqlspec/driver/_async.py +2 -15
  47. sqlspec/driver/_common.py +16 -95
  48. sqlspec/driver/_sync.py +2 -15
  49. sqlspec/driver/mixins/_result_tools.py +8 -29
  50. sqlspec/driver/mixins/_sql_translator.py +6 -8
  51. sqlspec/exceptions.py +1 -2
  52. sqlspec/loader.py +43 -115
  53. sqlspec/migrations/__init__.py +1 -1
  54. sqlspec/migrations/base.py +34 -45
  55. sqlspec/migrations/commands.py +34 -15
  56. sqlspec/migrations/loaders.py +1 -1
  57. sqlspec/migrations/runner.py +104 -19
  58. sqlspec/migrations/tracker.py +49 -2
  59. sqlspec/protocols.py +3 -6
  60. sqlspec/storage/__init__.py +4 -4
  61. sqlspec/storage/backends/fsspec.py +5 -6
  62. sqlspec/storage/backends/obstore.py +7 -8
  63. sqlspec/storage/registry.py +3 -3
  64. sqlspec/utils/__init__.py +2 -2
  65. sqlspec/utils/logging.py +6 -10
  66. sqlspec/utils/sync_tools.py +27 -4
  67. sqlspec/utils/text.py +6 -1
  68. {sqlspec-0.17.1.dist-info → sqlspec-0.18.0.dist-info}/METADATA +1 -1
  69. sqlspec-0.18.0.dist-info/RECORD +138 -0
  70. sqlspec/builder/_ddl_utils.py +0 -103
  71. sqlspec-0.17.1.dist-info/RECORD +0 -138
  72. {sqlspec-0.17.1.dist-info → sqlspec-0.18.0.dist-info}/WHEEL +0 -0
  73. {sqlspec-0.17.1.dist-info → sqlspec-0.18.0.dist-info}/entry_points.txt +0 -0
  74. {sqlspec-0.17.1.dist-info → sqlspec-0.18.0.dist-info}/licenses/LICENSE +0 -0
  75. {sqlspec-0.17.1.dist-info → sqlspec-0.18.0.dist-info}/licenses/NOTICE +0 -0
sqlspec/core/result.py CHANGED
@@ -6,12 +6,12 @@ including regular results and Apache Arrow format results.
6
6
  Components:
7
7
  - StatementResult: Abstract base class for SQL results
8
8
  - SQLResult: Main implementation for regular results
9
- - ArrowResult: Arrow-based results for high-performance data interchange
9
+ - ArrowResult: Arrow-based results for data interchange
10
10
 
11
11
  Features:
12
12
  - Consistent interface across all result types
13
13
  - Support for both regular and Arrow format results
14
- - Comprehensive result metadata and statistics
14
+ - Result metadata and statistics
15
15
  - Iterator support for result rows
16
16
  """
17
17
 
@@ -34,7 +34,7 @@ __all__ = ("ArrowResult", "SQLResult", "StatementResult")
34
34
  T = TypeVar("T")
35
35
 
36
36
 
37
- @mypyc_attr(allow_interpreted_subclasses=True)
37
+ @mypyc_attr(allow_interpreted_subclasses=False)
38
38
  class StatementResult(ABC):
39
39
  """Base class for SQL statement execution results.
40
40
 
@@ -123,12 +123,10 @@ class StatementResult(ABC):
123
123
  Returns:
124
124
  The type of SQL operation that produced this result.
125
125
  """
126
- if hasattr(self.statement, "operation_type"):
127
- return cast("OperationType", self.statement.operation_type)
128
- return "SELECT"
126
+ return self.statement.operation_type
129
127
 
130
128
 
131
- @mypyc_attr(allow_interpreted_subclasses=True)
129
+ @mypyc_attr(allow_interpreted_subclasses=False)
132
130
  class SQLResult(StatementResult):
133
131
  """Result class for SQL operations that return rows or affect rows.
134
132
 
@@ -154,6 +152,8 @@ class SQLResult(StatementResult):
154
152
  "total_statements",
155
153
  )
156
154
 
155
+ _operation_type: OperationType
156
+
157
157
  def __init__(
158
158
  self,
159
159
  statement: "SQL",
@@ -189,7 +189,6 @@ class SQLResult(StatementResult):
189
189
  self.operation_index = operation_index
190
190
  self.parameters = parameters
191
191
 
192
- # Optimize list initialization to avoid unnecessary object creation
193
192
  self.column_names = column_names or []
194
193
  self.total_count = total_count
195
194
  self.has_more = has_more
@@ -199,16 +198,15 @@ class SQLResult(StatementResult):
199
198
  self.total_statements = total_statements
200
199
  self.successful_statements = successful_statements
201
200
 
202
- # Optimize column name extraction and count calculation
203
201
  if not self.column_names and data and len(data) > 0:
204
202
  self.column_names = list(data[0].keys())
205
203
  if self.total_count is None:
206
204
  self.total_count = len(data) if data is not None else 0
207
205
 
208
206
  @property
209
- def operation_type(self) -> "OperationType":
207
+ def operation_type(self) -> OperationType:
210
208
  """Get operation type for this result."""
211
- return cast("OperationType", self._operation_type) # type: ignore[redundant-cast]
209
+ return self._operation_type
212
210
 
213
211
  def get_metadata(self, key: str, default: Any = None) -> Any:
214
212
  """Get metadata value by key.
@@ -261,7 +259,6 @@ class SQLResult(StatementResult):
261
259
  """
262
260
  op_type_upper = self.operation_type.upper()
263
261
  if op_type_upper == "SCRIPT":
264
- # Cache calculation to avoid redundant work
265
262
  failed_statements = self.total_statements - self.successful_statements
266
263
  return [
267
264
  {
@@ -478,26 +475,14 @@ class SQLResult(StatementResult):
478
475
  return next(iter(row.values()))
479
476
 
480
477
 
481
- @mypyc_attr(allow_interpreted_subclasses=True)
478
+ @mypyc_attr(allow_interpreted_subclasses=False)
482
479
  class ArrowResult(StatementResult):
483
480
  """Result class for SQL operations that return Apache Arrow data.
484
481
 
485
482
  This class is used when database drivers support returning results as
486
- Apache Arrow format for high-performance data interchange, especially
483
+ Apache Arrow format for data interchange, especially
487
484
  useful for analytics workloads and data science applications.
488
485
 
489
- Performance Features:
490
- - __slots__ optimization for memory efficiency
491
- - Direct Arrow table access without intermediate copying
492
- - Cached property evaluation for table metadata
493
- - MyPyC compatibility for critical operations
494
-
495
- Compatibility Features:
496
- - Complete interface preservation with existing ArrowResult
497
- - Same method signatures and behavior
498
- - Same error handling and exceptions
499
- - Identical Arrow table integration
500
-
501
486
  Args:
502
487
  statement: The original SQL statement that was executed.
503
488
  data: The Apache Arrow Table containing the result data.
@@ -516,7 +501,7 @@ class ArrowResult(StatementResult):
516
501
  metadata: Optional["dict[str, Any]"] = None,
517
502
  schema: Optional["dict[str, Any]"] = None,
518
503
  ) -> None:
519
- """Initialize Arrow result with enhanced performance.
504
+ """Initialize Arrow result.
520
505
 
521
506
  Args:
522
507
  statement: The original SQL statement that was executed.
sqlspec/core/splitter.py CHANGED
@@ -24,7 +24,7 @@ from abc import ABC, abstractmethod
24
24
  from collections.abc import Generator
25
25
  from enum import Enum
26
26
  from re import Pattern
27
- from typing import Any, Callable, Optional, Union
27
+ from typing import Any, Callable, Final, Optional, Union, cast
28
28
 
29
29
  from mypy_extensions import mypyc_attr
30
30
  from typing_extensions import TypeAlias
@@ -45,11 +45,11 @@ __all__ = (
45
45
 
46
46
  logger = get_logger("sqlspec.core.splitter")
47
47
 
48
- DEFAULT_PATTERN_CACHE_SIZE = 1000 # Compiled regex patterns
49
- DEFAULT_RESULT_CACHE_SIZE = 5000 # Split results
50
- DEFAULT_CACHE_TTL = 3600 # 1 hour TTL
48
+ DEFAULT_PATTERN_CACHE_SIZE: Final = 1000
49
+ DEFAULT_RESULT_CACHE_SIZE: Final = 5000
50
+ DEFAULT_CACHE_TTL: Final = 3600
51
51
 
52
- DIALECT_CONFIG_SLOTS = (
52
+ DIALECT_CONFIG_SLOTS: Final = (
53
53
  "_block_starters",
54
54
  "_block_enders",
55
55
  "_statement_terminators",
@@ -59,9 +59,9 @@ DIALECT_CONFIG_SLOTS = (
59
59
  "_name",
60
60
  )
61
61
 
62
- TOKEN_SLOTS = ("type", "value", "line", "column", "position")
62
+ TOKEN_SLOTS: Final = ("type", "value", "line", "column", "position")
63
63
 
64
- SPLITTER_SLOTS = (
64
+ SPLITTER_SLOTS: Final = (
65
65
  "_dialect",
66
66
  "_strip_trailing_semicolon",
67
67
  "_token_patterns",
@@ -86,7 +86,7 @@ class TokenType(Enum):
86
86
  OTHER = "OTHER"
87
87
 
88
88
 
89
- @mypyc_attr(allow_interpreted_subclasses=True)
89
+ @mypyc_attr(allow_interpreted_subclasses=False)
90
90
  class Token:
91
91
  """SQL token with metadata."""
92
92
 
@@ -108,7 +108,7 @@ TokenPattern: TypeAlias = Union[str, TokenHandler]
108
108
  CompiledTokenPattern: TypeAlias = Union[Pattern[str], TokenHandler]
109
109
 
110
110
 
111
- @mypyc_attr(allow_interpreted_subclasses=True)
111
+ @mypyc_attr(allow_interpreted_subclasses=False)
112
112
  class DialectConfig(ABC):
113
113
  """Abstract base class for SQL dialect configurations."""
114
114
 
@@ -542,32 +542,28 @@ class BigQueryDialectConfig(DialectConfig):
542
542
  return self._statement_terminators
543
543
 
544
544
 
545
- _pattern_cache: Optional[UnifiedCache[list[tuple[TokenType, CompiledTokenPattern]]]] = None
546
- _result_cache: Optional[UnifiedCache[list[str]]] = None
545
+ _pattern_cache: Optional[UnifiedCache] = None
546
+ _result_cache: Optional[UnifiedCache] = None
547
547
  _cache_lock = threading.Lock()
548
548
 
549
549
 
550
- def _get_pattern_cache() -> UnifiedCache[list[tuple[TokenType, CompiledTokenPattern]]]:
550
+ def _get_pattern_cache() -> UnifiedCache:
551
551
  """Get or create the pattern compilation cache."""
552
552
  global _pattern_cache
553
553
  if _pattern_cache is None:
554
554
  with _cache_lock:
555
555
  if _pattern_cache is None:
556
- _pattern_cache = UnifiedCache[list[tuple[TokenType, CompiledTokenPattern]]](
557
- max_size=DEFAULT_PATTERN_CACHE_SIZE, ttl_seconds=DEFAULT_CACHE_TTL
558
- )
556
+ _pattern_cache = UnifiedCache(max_size=DEFAULT_PATTERN_CACHE_SIZE, ttl_seconds=DEFAULT_CACHE_TTL)
559
557
  return _pattern_cache
560
558
 
561
559
 
562
- def _get_result_cache() -> UnifiedCache[list[str]]:
560
+ def _get_result_cache() -> UnifiedCache:
563
561
  """Get or create the result cache."""
564
562
  global _result_cache
565
563
  if _result_cache is None:
566
564
  with _cache_lock:
567
565
  if _result_cache is None:
568
- _result_cache = UnifiedCache[list[str]](
569
- max_size=DEFAULT_RESULT_CACHE_SIZE, ttl_seconds=DEFAULT_CACHE_TTL
570
- )
566
+ _result_cache = UnifiedCache(max_size=DEFAULT_RESULT_CACHE_SIZE, ttl_seconds=DEFAULT_CACHE_TTL)
571
567
  return _result_cache
572
568
 
573
569
 
@@ -596,7 +592,7 @@ class StatementSplitter:
596
592
 
597
593
  cached_patterns = self._pattern_cache.get(cache_key)
598
594
  if cached_patterns is not None:
599
- return cached_patterns
595
+ return cast("list[tuple[TokenType, CompiledTokenPattern]]", cached_patterns)
600
596
 
601
597
  compiled: list[tuple[TokenType, CompiledTokenPattern]] = []
602
598
  for token_type, pattern in self._token_patterns:
@@ -660,7 +656,7 @@ class StatementSplitter:
660
656
 
661
657
  cached_result = self._result_cache.get(cache_key)
662
658
  if cached_result is not None:
663
- return cached_result
659
+ return cast("list[str]", cached_result)
664
660
 
665
661
  statements = self._do_split(sql)
666
662