sqlspec 0.24.1__py3-none-any.whl → 0.25.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 (42) hide show
  1. sqlspec/_sql.py +11 -15
  2. sqlspec/_typing.py +2 -0
  3. sqlspec/adapters/adbc/driver.py +2 -2
  4. sqlspec/adapters/oracledb/driver.py +5 -0
  5. sqlspec/adapters/psycopg/config.py +2 -4
  6. sqlspec/base.py +3 -4
  7. sqlspec/builder/_base.py +55 -13
  8. sqlspec/builder/_column.py +9 -0
  9. sqlspec/builder/_ddl.py +7 -7
  10. sqlspec/builder/_insert.py +10 -6
  11. sqlspec/builder/_parsing_utils.py +23 -4
  12. sqlspec/builder/_update.py +1 -1
  13. sqlspec/builder/mixins/_cte_and_set_ops.py +31 -22
  14. sqlspec/builder/mixins/_delete_operations.py +12 -7
  15. sqlspec/builder/mixins/_insert_operations.py +50 -36
  16. sqlspec/builder/mixins/_join_operations.py +1 -0
  17. sqlspec/builder/mixins/_merge_operations.py +54 -28
  18. sqlspec/builder/mixins/_order_limit_operations.py +1 -0
  19. sqlspec/builder/mixins/_pivot_operations.py +1 -0
  20. sqlspec/builder/mixins/_select_operations.py +42 -14
  21. sqlspec/builder/mixins/_update_operations.py +30 -18
  22. sqlspec/builder/mixins/_where_clause.py +48 -60
  23. sqlspec/core/__init__.py +3 -2
  24. sqlspec/core/cache.py +297 -351
  25. sqlspec/core/compiler.py +5 -3
  26. sqlspec/core/filters.py +246 -213
  27. sqlspec/core/hashing.py +9 -11
  28. sqlspec/core/parameters.py +20 -7
  29. sqlspec/core/statement.py +67 -12
  30. sqlspec/driver/_async.py +2 -2
  31. sqlspec/driver/_common.py +31 -14
  32. sqlspec/driver/_sync.py +2 -2
  33. sqlspec/driver/mixins/_result_tools.py +60 -7
  34. sqlspec/loader.py +8 -9
  35. sqlspec/storage/backends/fsspec.py +1 -0
  36. sqlspec/typing.py +2 -0
  37. {sqlspec-0.24.1.dist-info → sqlspec-0.25.0.dist-info}/METADATA +1 -1
  38. {sqlspec-0.24.1.dist-info → sqlspec-0.25.0.dist-info}/RECORD +42 -42
  39. {sqlspec-0.24.1.dist-info → sqlspec-0.25.0.dist-info}/WHEEL +0 -0
  40. {sqlspec-0.24.1.dist-info → sqlspec-0.25.0.dist-info}/entry_points.txt +0 -0
  41. {sqlspec-0.24.1.dist-info → sqlspec-0.25.0.dist-info}/licenses/LICENSE +0 -0
  42. {sqlspec-0.24.1.dist-info → sqlspec-0.25.0.dist-info}/licenses/NOTICE +0 -0
sqlspec/core/hashing.py CHANGED
@@ -185,26 +185,24 @@ def hash_sql_statement(statement: "SQL") -> str:
185
185
  """
186
186
  from sqlspec.utils.type_guards import is_expression
187
187
 
188
- if is_expression(statement._statement):
189
- expr_hash = hash_expression(statement._statement)
190
- else:
191
- expr_hash = hash(statement._raw_sql)
188
+ stmt_expr = statement.statement_expression
189
+ expr_hash = hash_expression(stmt_expr) if is_expression(stmt_expr) else hash(statement.raw_sql)
192
190
 
193
191
  param_hash = hash_parameters(
194
- positional_parameters=statement._positional_parameters,
195
- named_parameters=statement._named_parameters,
196
- original_parameters=statement._original_parameters,
192
+ positional_parameters=statement.positional_parameters,
193
+ named_parameters=statement.named_parameters,
194
+ original_parameters=statement.original_parameters,
197
195
  )
198
196
 
199
- filter_hash = hash_filters(statement._filters)
197
+ filter_hash = hash_filters(statement.filters)
200
198
 
201
199
  state_components = [
202
200
  expr_hash,
203
201
  param_hash,
204
202
  filter_hash,
205
- hash(statement._dialect),
206
- hash(statement._is_many),
207
- hash(statement._is_script),
203
+ hash(statement.dialect),
204
+ hash(statement.is_many),
205
+ hash(statement.is_script),
208
206
  ]
209
207
 
210
208
  return f"sql:{hash(tuple(state_components))}"
@@ -755,17 +755,30 @@ class ParameterConverter:
755
755
  parameter_styles = {p.style for p in param_info}
756
756
  has_mixed_styles = len(parameter_styles) > 1
757
757
 
758
+ # Build unique parameter mapping to avoid duplicates when same parameter appears multiple times
759
+ unique_params: dict[str, Any] = {}
760
+ param_order: list[str] = []
761
+
758
762
  if has_mixed_styles:
759
763
  param_keys = list(parameters.keys())
760
764
  for param in param_info:
761
- value, found = self._extract_param_value_mixed_styles(param, parameters, param_keys)
762
- if found:
763
- param_values.append(value)
765
+ param_key = param.placeholder_text
766
+ if param_key not in unique_params:
767
+ value, found = self._extract_param_value_mixed_styles(param, parameters, param_keys)
768
+ if found:
769
+ unique_params[param_key] = value
770
+ param_order.append(param_key)
764
771
  else:
765
772
  for param in param_info:
766
- value, found = self._extract_param_value_single_style(param, parameters)
767
- if found:
768
- param_values.append(value)
773
+ param_key = param.placeholder_text
774
+ if param_key not in unique_params:
775
+ value, found = self._extract_param_value_single_style(param, parameters)
776
+ if found:
777
+ unique_params[param_key] = value
778
+ param_order.append(param_key)
779
+
780
+ # Build parameter values list from unique parameters in order
781
+ param_values = [unique_params[param_key] for param_key in param_order]
769
782
 
770
783
  if preserve_parameter_format and original_parameters is not None:
771
784
  return self._preserve_original_format(param_values, original_parameters)
@@ -1064,7 +1077,7 @@ class ParameterProcessor:
1064
1077
 
1065
1078
  return processed_sql, processed_parameters
1066
1079
 
1067
- def _get_sqlglot_compatible_sql(
1080
+ def get_sqlglot_compatible_sql(
1068
1081
  self, sql: str, parameters: Any, config: ParameterStyleConfig, dialect: Optional[str] = None
1069
1082
  ) -> "tuple[str, Any]":
1070
1083
  """Get SQL normalized for parsing only (Phase 1 only).
sqlspec/core/statement.py CHANGED
@@ -18,6 +18,7 @@ from sqlspec.utils.type_guards import is_statement_filter, supports_where
18
18
  if TYPE_CHECKING:
19
19
  from sqlglot.dialects.dialect import DialectType
20
20
 
21
+ from sqlspec.core.cache import FiltersView
21
22
  from sqlspec.core.filters import StatementFilter
22
23
 
23
24
 
@@ -161,14 +162,14 @@ class SQL:
161
162
  self._process_parameters(*parameters, **kwargs)
162
163
 
163
164
  def _create_auto_config(
164
- self, statement: "Union[str, exp.Expression, 'SQL']", parameters: tuple, kwargs: dict[str, Any]
165
+ self, _statement: "Union[str, exp.Expression, 'SQL']", _parameters: tuple, _kwargs: dict[str, Any]
165
166
  ) -> "StatementConfig":
166
167
  """Create default StatementConfig when none provided.
167
168
 
168
169
  Args:
169
- statement: The SQL statement
170
- parameters: Statement parameters
171
- kwargs: Additional keyword arguments
170
+ _statement: The SQL statement (unused)
171
+ _parameters: Statement parameters (unused)
172
+ _kwargs: Additional keyword arguments (unused)
172
173
 
173
174
  Returns:
174
175
  Default StatementConfig instance
@@ -196,14 +197,14 @@ class SQL:
196
197
  Args:
197
198
  sql_obj: Existing SQL object to copy from
198
199
  """
199
- self._raw_sql = sql_obj._raw_sql
200
- self._filters = sql_obj._filters.copy()
201
- self._named_parameters = sql_obj._named_parameters.copy()
202
- self._positional_parameters = sql_obj._positional_parameters.copy()
203
- self._is_many = sql_obj._is_many
204
- self._is_script = sql_obj._is_script
205
- if sql_obj._processed_state is not Empty:
206
- self._processed_state = sql_obj._processed_state
200
+ self._raw_sql = sql_obj.raw_sql
201
+ self._filters = sql_obj.filters.copy()
202
+ self._named_parameters = sql_obj.named_parameters.copy()
203
+ self._positional_parameters = sql_obj.positional_parameters.copy()
204
+ self._is_many = sql_obj.is_many
205
+ self._is_script = sql_obj.is_script
206
+ if sql_obj.is_processed:
207
+ self._processed_state = sql_obj.get_processed_state()
207
208
 
208
209
  def _should_auto_detect_many(self, parameters: tuple) -> bool:
209
210
  """Detect execute_many mode from parameter structure.
@@ -270,6 +271,15 @@ class SQL:
270
271
  """Get the raw SQL string."""
271
272
  return self._raw_sql
272
273
 
274
+ @property
275
+ def raw_sql(self) -> str:
276
+ """Get raw SQL string (public API).
277
+
278
+ Returns:
279
+ The raw SQL string
280
+ """
281
+ return self._raw_sql
282
+
273
283
  @property
274
284
  def parameters(self) -> Any:
275
285
  """Get the original parameters."""
@@ -277,6 +287,21 @@ class SQL:
277
287
  return self._named_parameters
278
288
  return self._positional_parameters or []
279
289
 
290
+ @property
291
+ def positional_parameters(self) -> "list[Any]":
292
+ """Get positional parameters (public API)."""
293
+ return self._positional_parameters or []
294
+
295
+ @property
296
+ def named_parameters(self) -> "dict[str, Any]":
297
+ """Get named parameters (public API)."""
298
+ return self._named_parameters
299
+
300
+ @property
301
+ def original_parameters(self) -> Any:
302
+ """Get original parameters (public API)."""
303
+ return self._original_parameters
304
+
280
305
  @property
281
306
  def operation_type(self) -> "OperationType":
282
307
  """SQL operation type."""
@@ -301,6 +326,25 @@ class SQL:
301
326
  """Applied filters."""
302
327
  return self._filters.copy()
303
328
 
329
+ def get_filters_view(self) -> "FiltersView":
330
+ """Get zero-copy filters view (public API).
331
+
332
+ Returns:
333
+ Read-only view of filters without copying
334
+ """
335
+ from sqlspec.core.cache import FiltersView
336
+
337
+ return FiltersView(self._filters)
338
+
339
+ @property
340
+ def is_processed(self) -> bool:
341
+ """Check if SQL has been processed (public API)."""
342
+ return self._processed_state is not Empty
343
+
344
+ def get_processed_state(self) -> Any:
345
+ """Get processed state (public API)."""
346
+ return self._processed_state
347
+
304
348
  @property
305
349
  def dialect(self) -> "Optional[str]":
306
350
  """SQL dialect."""
@@ -311,6 +355,17 @@ class SQL:
311
355
  """Internal SQLGlot expression."""
312
356
  return self.expression
313
357
 
358
+ @property
359
+ def statement_expression(self) -> "Optional[exp.Expression]":
360
+ """Get parsed statement expression (public API).
361
+
362
+ Returns:
363
+ Parsed SQLGlot expression or None if not parsed
364
+ """
365
+ if self._processed_state is not Empty:
366
+ return self._processed_state.parsed_expression
367
+ return None
368
+
314
369
  @property
315
370
  def is_many(self) -> bool:
316
371
  """Check if this is execute_many."""
sqlspec/driver/_async.py CHANGED
@@ -186,10 +186,10 @@ class AsyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, To
186
186
  config = statement_config or self.statement_config
187
187
 
188
188
  if isinstance(statement, SQL):
189
- sql_statement = SQL(statement._raw_sql, parameters, statement_config=config, is_many=True, **kwargs)
189
+ sql_statement = SQL(statement.raw_sql, parameters, statement_config=config, is_many=True, **kwargs)
190
190
  else:
191
191
  base_statement = self.prepare_statement(statement, filters, statement_config=config, kwargs=kwargs)
192
- sql_statement = SQL(base_statement._raw_sql, parameters, statement_config=config, is_many=True, **kwargs)
192
+ sql_statement = SQL(base_statement.raw_sql, parameters, statement_config=config, is_many=True, **kwargs)
193
193
 
194
194
  return await self.dispatch_statement_execution(statement=sql_statement, connection=self.connection)
195
195
 
sqlspec/driver/_common.py CHANGED
@@ -7,7 +7,7 @@ from sqlglot import exp
7
7
 
8
8
  from sqlspec.builder import QueryBuilder
9
9
  from sqlspec.core import SQL, ParameterStyle, SQLResult, Statement, StatementConfig, TypedParameter
10
- from sqlspec.core.cache import get_cache_config, sql_cache
10
+ from sqlspec.core.cache import CachedStatement, get_cache, get_cache_config
11
11
  from sqlspec.core.splitter import split_sql_script
12
12
  from sqlspec.exceptions import ImproperConfigurationError
13
13
  from sqlspec.utils.logging import get_logger
@@ -206,16 +206,16 @@ class CommonDriverAttributesMixin:
206
206
  sql_statement = statement.to_statement(statement_config)
207
207
  if parameters or kwargs:
208
208
  merged_parameters = (
209
- (*sql_statement._positional_parameters, *parameters)
209
+ (*sql_statement.positional_parameters, *parameters)
210
210
  if parameters
211
- else sql_statement._positional_parameters
211
+ else sql_statement.positional_parameters
212
212
  )
213
213
  return SQL(sql_statement.sql, *merged_parameters, statement_config=statement_config, **kwargs)
214
214
  return sql_statement
215
215
  if isinstance(statement, SQL):
216
216
  if parameters or kwargs:
217
217
  merged_parameters = (
218
- (*statement._positional_parameters, *parameters) if parameters else statement._positional_parameters
218
+ (*statement.positional_parameters, *parameters) if parameters else statement.positional_parameters
219
219
  )
220
220
  return SQL(statement.sql, *merged_parameters, statement_config=statement_config, **kwargs)
221
221
  needs_rebuild = False
@@ -232,14 +232,14 @@ class CommonDriverAttributesMixin:
232
232
  needs_rebuild = True
233
233
 
234
234
  if needs_rebuild:
235
- sql_text = statement._raw_sql or statement.sql
235
+ sql_text = statement.raw_sql or statement.sql
236
236
 
237
237
  if statement.is_many and statement.parameters:
238
238
  new_sql = SQL(sql_text, statement.parameters, statement_config=statement_config, is_many=True)
239
- elif statement._named_parameters:
240
- new_sql = SQL(sql_text, statement_config=statement_config, **statement._named_parameters)
239
+ elif statement.named_parameters:
240
+ new_sql = SQL(sql_text, statement_config=statement_config, **statement.named_parameters)
241
241
  else:
242
- new_sql = SQL(sql_text, *statement._positional_parameters, statement_config=statement_config)
242
+ new_sql = SQL(sql_text, *statement.positional_parameters, statement_config=statement_config)
243
243
 
244
244
  return new_sql
245
245
  return statement
@@ -413,9 +413,10 @@ class CommonDriverAttributesMixin:
413
413
  cache_key = None
414
414
  if cache_config.compiled_cache_enabled and statement_config.enable_caching:
415
415
  cache_key = self._generate_compilation_cache_key(statement, statement_config, flatten_single_parameters)
416
- cached_result = sql_cache.get(cache_key)
417
- if cached_result is not None:
418
- return cached_result
416
+ cache = get_cache()
417
+ cached_result = cache.get("statement", cache_key, str(statement.dialect) if statement.dialect else None)
418
+ if cached_result is not None and isinstance(cached_result, CachedStatement):
419
+ return cached_result.compiled_sql, cached_result.parameters
419
420
 
420
421
  prepared_statement = self.prepare_statement(statement, statement_config=statement_config)
421
422
  compiled_sql, execution_parameters = prepared_statement.compile()
@@ -430,7 +431,23 @@ class CommonDriverAttributesMixin:
430
431
  )
431
432
 
432
433
  if cache_key is not None:
433
- sql_cache.set(cache_key, (compiled_sql, prepared_parameters))
434
+ cache = get_cache()
435
+ cached_statement = CachedStatement(
436
+ compiled_sql=compiled_sql,
437
+ parameters=tuple(prepared_parameters)
438
+ if isinstance(prepared_parameters, list)
439
+ else (
440
+ prepared_parameters
441
+ if prepared_parameters is None
442
+ else (
443
+ tuple(prepared_parameters)
444
+ if not isinstance(prepared_parameters, tuple)
445
+ else prepared_parameters
446
+ )
447
+ ),
448
+ expression=statement.expression,
449
+ )
450
+ cache.put("statement", cache_key, cached_statement, str(statement.dialect) if statement.dialect else None)
434
451
 
435
452
  return compiled_sql, prepared_parameters
436
453
 
@@ -562,8 +579,8 @@ class CommonDriverAttributesMixin:
562
579
  count_expr.set("limit", None)
563
580
  count_expr.set("offset", None)
564
581
 
565
- return SQL(count_expr, *original_sql._positional_parameters, statement_config=original_sql.statement_config)
582
+ return SQL(count_expr, *original_sql.positional_parameters, statement_config=original_sql.statement_config)
566
583
 
567
584
  subquery = cast("exp.Select", expr).subquery(alias="total_query")
568
585
  count_expr = exp.select(exp.Count(this=exp.Star())).from_(subquery)
569
- return SQL(count_expr, *original_sql._positional_parameters, statement_config=original_sql.statement_config)
586
+ return SQL(count_expr, *original_sql.positional_parameters, statement_config=original_sql.statement_config)
sqlspec/driver/_sync.py CHANGED
@@ -186,10 +186,10 @@ class SyncDriverAdapterBase(CommonDriverAttributesMixin, SQLTranslatorMixin, ToS
186
186
  config = statement_config or self.statement_config
187
187
 
188
188
  if isinstance(statement, SQL):
189
- sql_statement = SQL(statement._raw_sql, parameters, statement_config=config, is_many=True, **kwargs)
189
+ sql_statement = SQL(statement.raw_sql, parameters, statement_config=config, is_many=True, **kwargs)
190
190
  else:
191
191
  base_statement = self.prepare_statement(statement, filters, statement_config=config, kwargs=kwargs)
192
- sql_statement = SQL(base_statement._raw_sql, parameters, statement_config=config, is_many=True, **kwargs)
192
+ sql_statement = SQL(base_statement.raw_sql, parameters, statement_config=config, is_many=True, **kwargs)
193
193
 
194
194
  return self.dispatch_statement_execution(statement=sql_statement, connection=self.connection)
195
195
 
@@ -15,6 +15,7 @@ from mypy_extensions import trait
15
15
  from sqlspec.exceptions import SQLSpecError
16
16
  from sqlspec.typing import (
17
17
  CATTRS_INSTALLED,
18
+ NUMPY_INSTALLED,
18
19
  ModelDTOT,
19
20
  ModelT,
20
21
  attrs_asdict,
@@ -41,12 +42,36 @@ logger = logging.getLogger(__name__)
41
42
 
42
43
 
43
44
  _DATETIME_TYPES: Final[set[type]] = {datetime.datetime, datetime.date, datetime.time}
45
+
46
+
47
+ def _is_list_type_target(target_type: Any) -> bool:
48
+ """Check if target type is a list type (e.g., list[float])."""
49
+ try:
50
+ return hasattr(target_type, "__origin__") and target_type.__origin__ is list
51
+ except (AttributeError, TypeError):
52
+ return False
53
+
54
+
55
+ def _convert_numpy_to_list(target_type: Any, value: Any) -> Any:
56
+ """Convert numpy array to list if target is a list type."""
57
+ if not NUMPY_INSTALLED:
58
+ return value
59
+
60
+ import numpy as np
61
+
62
+ if isinstance(value, np.ndarray) and _is_list_type_target(target_type):
63
+ return value.tolist()
64
+
65
+ return value
66
+
67
+
44
68
  _DEFAULT_TYPE_DECODERS: Final[list[tuple[Callable[[Any], bool], Callable[[Any, Any], Any]]]] = [
45
69
  (lambda x: x is UUID, lambda t, v: t(v.hex)),
46
70
  (lambda x: x is datetime.datetime, lambda t, v: t(v.isoformat())),
47
71
  (lambda x: x is datetime.date, lambda t, v: t(v.isoformat())),
48
72
  (lambda x: x is datetime.time, lambda t, v: t(v.isoformat())),
49
73
  (lambda x: x is Enum, lambda t, v: t(v.value)),
74
+ (_is_list_type_target, _convert_numpy_to_list),
50
75
  ]
51
76
 
52
77
 
@@ -63,6 +88,13 @@ def _default_msgspec_deserializer(
63
88
  Returns:
64
89
  Converted value or original value if conversion not applicable
65
90
  """
91
+ # Handle numpy arrays first for list types
92
+ if NUMPY_INSTALLED:
93
+ import numpy as np
94
+
95
+ if isinstance(value, np.ndarray) and _is_list_type_target(target_type):
96
+ return value.tolist()
97
+
66
98
  if type_decoders:
67
99
  for predicate, decoder in type_decoders:
68
100
  if predicate(target_type):
@@ -71,17 +103,19 @@ def _default_msgspec_deserializer(
71
103
  if target_type is UUID and isinstance(value, UUID):
72
104
  return value.hex
73
105
 
74
- if target_type in _DATETIME_TYPES:
75
- try:
76
- return value.isoformat()
77
- except AttributeError:
78
- pass
106
+ if target_type in _DATETIME_TYPES and hasattr(value, "isoformat"):
107
+ return value.isoformat() # pyright: ignore
79
108
 
80
109
  if isinstance(target_type, type) and issubclass(target_type, Enum) and isinstance(value, Enum):
81
110
  return value.value
82
111
 
83
- if isinstance(value, target_type):
84
- return value
112
+ # Check if value is already the correct type (but avoid parameterized generics)
113
+ try:
114
+ if isinstance(target_type, type) and isinstance(value, target_type):
115
+ return value
116
+ except TypeError:
117
+ # Handle parameterized generics like list[int] which can't be used with isinstance
118
+ pass
85
119
 
86
120
  if isinstance(target_type, type):
87
121
  try:
@@ -190,6 +224,25 @@ class ToSchemaMixin:
190
224
  logger.debug("Field name transformation failed for msgspec schema: %s", e)
191
225
  transformed_data = data
192
226
 
227
+ # Pre-process numpy arrays to lists before msgspec conversion
228
+ if NUMPY_INSTALLED:
229
+ try:
230
+ import numpy as np
231
+
232
+ def _convert_numpy_arrays_in_data(obj: Any) -> Any:
233
+ """Recursively convert numpy arrays to lists in data structures."""
234
+ if isinstance(obj, np.ndarray):
235
+ return obj.tolist()
236
+ if isinstance(obj, dict):
237
+ return {k: _convert_numpy_arrays_in_data(v) for k, v in obj.items()}
238
+ if isinstance(obj, (list, tuple)):
239
+ return type(obj)(_convert_numpy_arrays_in_data(item) for item in obj)
240
+ return obj
241
+
242
+ transformed_data = _convert_numpy_arrays_in_data(transformed_data)
243
+ except ImportError:
244
+ pass
245
+
193
246
  if not isinstance(transformed_data, Sequence):
194
247
  return convert(obj=transformed_data, type=schema_type, from_attributes=True, dec_hook=deserializer)
195
248
  return convert(obj=transformed_data, type=list[schema_type], from_attributes=True, dec_hook=deserializer) # type: ignore[valid-type]
sqlspec/loader.py CHANGED
@@ -12,7 +12,7 @@ from pathlib import Path
12
12
  from typing import TYPE_CHECKING, Any, Final, Optional, Union
13
13
  from urllib.parse import unquote, urlparse
14
14
 
15
- from sqlspec.core.cache import CacheKey, get_cache_config, get_default_cache
15
+ from sqlspec.core.cache import get_cache, get_cache_config
16
16
  from sqlspec.core.statement import SQL
17
17
  from sqlspec.exceptions import SQLFileNotFoundError, SQLFileParseError, StorageOperationFailedError
18
18
  from sqlspec.storage.registry import storage_registry as default_storage_registry
@@ -438,9 +438,8 @@ class SQLFileLoader:
438
438
  return
439
439
 
440
440
  cache_key_str = self._generate_file_cache_key(file_path)
441
- cache_key = CacheKey((cache_key_str,))
442
- unified_cache = get_default_cache()
443
- cached_file = unified_cache.get(cache_key)
441
+ cache = get_cache()
442
+ cached_file = cache.get("file", cache_key_str)
444
443
 
445
444
  if (
446
445
  cached_file is not None
@@ -475,7 +474,7 @@ class SQLFileLoader:
475
474
  file_statements[stored_name] = self._queries[query_name]
476
475
 
477
476
  cached_file_data = CachedSQLFile(sql_file=sql_file, parsed_statements=file_statements)
478
- unified_cache.put(cache_key, cached_file_data)
477
+ cache.put("file", cache_key_str, cached_file_data)
479
478
 
480
479
  def _load_file_without_cache(self, file_path: Union[str, Path], namespace: Optional[str]) -> None:
481
480
  """Load a single SQL file without using cache.
@@ -592,15 +591,15 @@ class SQLFileLoader:
592
591
 
593
592
  cache_config = get_cache_config()
594
593
  if cache_config.compiled_cache_enabled:
595
- unified_cache = get_default_cache()
596
- unified_cache.clear()
594
+ cache = get_cache()
595
+ cache.clear()
597
596
 
598
597
  def clear_file_cache(self) -> None:
599
598
  """Clear the file cache only, keeping loaded queries."""
600
599
  cache_config = get_cache_config()
601
600
  if cache_config.compiled_cache_enabled:
602
- unified_cache = get_default_cache()
603
- unified_cache.clear()
601
+ cache = get_cache()
602
+ cache.clear()
604
603
 
605
604
  def get_query_text(self, name: str) -> str:
606
605
  """Get raw SQL text for a query.
@@ -1,3 +1,4 @@
1
+ # pyright: reportPrivateUsage=false
1
2
  import logging
2
3
  from pathlib import Path
3
4
  from typing import TYPE_CHECKING, Any, Optional, Union
sqlspec/typing.py CHANGED
@@ -12,6 +12,7 @@ from sqlspec._typing import (
12
12
  FSSPEC_INSTALLED,
13
13
  LITESTAR_INSTALLED,
14
14
  MSGSPEC_INSTALLED,
15
+ NUMPY_INSTALLED,
15
16
  OBSTORE_INSTALLED,
16
17
  OPENTELEMETRY_INSTALLED,
17
18
  PGVECTOR_INSTALLED,
@@ -187,6 +188,7 @@ __all__ = (
187
188
  "FSSPEC_INSTALLED",
188
189
  "LITESTAR_INSTALLED",
189
190
  "MSGSPEC_INSTALLED",
191
+ "NUMPY_INSTALLED",
190
192
  "OBSTORE_INSTALLED",
191
193
  "OPENTELEMETRY_INSTALLED",
192
194
  "PGVECTOR_INSTALLED",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlspec
3
- Version: 0.24.1
3
+ Version: 0.25.0
4
4
  Summary: SQL Experiments in Python
5
5
  Project-URL: Discord, https://discord.gg/litestar
6
6
  Project-URL: Issue, https://github.com/litestar-org/sqlspec/issues/