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
@@ -1,7 +1,7 @@
1
- """Psqlpy driver implementation.
1
+ """Psqlpy driver implementation for PostgreSQL connectivity.
2
2
 
3
- Provides PostgreSQL connectivity with parameter style conversion,
4
- type coercion, error handling, and transaction management.
3
+ Provides parameter style conversion, type coercion, error handling,
4
+ and transaction management.
5
5
  """
6
6
 
7
7
  import datetime
@@ -39,7 +39,7 @@ psqlpy_statement_config = StatementConfig(
39
39
  default_execution_parameter_style=ParameterStyle.NUMERIC,
40
40
  supported_execution_parameter_styles={ParameterStyle.NUMERIC},
41
41
  type_coercion_map={tuple: list, decimal.Decimal: float},
42
- has_native_list_expansion=True,
42
+ has_native_list_expansion=False,
43
43
  needs_static_script_compilation=False,
44
44
  allow_mixed_parameter_styles=False,
45
45
  preserve_parameter_format=True,
@@ -72,8 +72,8 @@ SPECIAL_TYPE_REGEX: Final[re.Pattern[str]] = re.compile(
72
72
  def _detect_postgresql_type(value: str) -> Optional[str]:
73
73
  """Detect PostgreSQL data type from string value.
74
74
 
75
- Detects common PostgreSQL types including UUID, IP addresses,
76
- timestamps, JSON, and arrays.
75
+ Args:
76
+ value: String value to analyze
77
77
 
78
78
  Returns:
79
79
  Type name if detected, None otherwise.
@@ -101,7 +101,14 @@ def _detect_postgresql_type(value: str) -> Optional[str]:
101
101
 
102
102
 
103
103
  def _convert_uuid(value: str) -> Any:
104
- """Convert UUID string to UUID object."""
104
+ """Convert UUID string to UUID object.
105
+
106
+ Args:
107
+ value: UUID string to convert
108
+
109
+ Returns:
110
+ UUID object or original value if conversion fails
111
+ """
105
112
  try:
106
113
  clean_uuid = value.replace("-", "").lower()
107
114
  uuid_length = 32
@@ -114,7 +121,14 @@ def _convert_uuid(value: str) -> Any:
114
121
 
115
122
 
116
123
  def _convert_iso_datetime(value: str) -> Any:
117
- """Convert ISO datetime string to datetime object."""
124
+ """Convert ISO datetime string to datetime object.
125
+
126
+ Args:
127
+ value: ISO datetime string to convert
128
+
129
+ Returns:
130
+ datetime object or original value if conversion fails
131
+ """
118
132
  try:
119
133
  normalized = value.replace("Z", "+00:00")
120
134
  return datetime.datetime.fromisoformat(normalized)
@@ -123,7 +137,14 @@ def _convert_iso_datetime(value: str) -> Any:
123
137
 
124
138
 
125
139
  def _convert_iso_date(value: str) -> Any:
126
- """Convert ISO date string to date object."""
140
+ """Convert ISO date string to date object.
141
+
142
+ Args:
143
+ value: ISO date string to convert
144
+
145
+ Returns:
146
+ date object or original value if conversion fails
147
+ """
127
148
  try:
128
149
  return datetime.date.fromisoformat(value)
129
150
  except ValueError:
@@ -131,7 +152,14 @@ def _convert_iso_date(value: str) -> Any:
131
152
 
132
153
 
133
154
  def _validate_json(value: str) -> str:
134
- """Validate JSON string but keep as string for psqlpy."""
155
+ """Validate JSON string format.
156
+
157
+ Args:
158
+ value: JSON string to validate
159
+
160
+ Returns:
161
+ Original string value
162
+ """
135
163
  from sqlspec.utils.serializers import from_json
136
164
 
137
165
  try:
@@ -142,7 +170,14 @@ def _validate_json(value: str) -> str:
142
170
 
143
171
 
144
172
  def _passthrough(value: str) -> str:
145
- """Pass value through unchanged."""
173
+ """Pass value through unchanged.
174
+
175
+ Args:
176
+ value: String value to pass through
177
+
178
+ Returns:
179
+ Original value unchanged
180
+ """
146
181
  return value
147
182
 
148
183
 
@@ -161,15 +196,13 @@ _PSQLPY_TYPE_CONVERTERS: dict[str, Any] = {
161
196
 
162
197
 
163
198
  def _convert_psqlpy_parameters(value: Any) -> Any:
164
- """Convert parameters for Psqlpy compatibility.
165
-
166
- Performs type conversions based on detected PostgreSQL types.
199
+ """Convert parameters for psqlpy compatibility.
167
200
 
168
201
  Args:
169
202
  value: Parameter value to convert
170
203
 
171
204
  Returns:
172
- Converted value suitable for psqlpy/PostgreSQL
205
+ Converted value suitable for psqlpy execution
173
206
  """
174
207
  if isinstance(value, str):
175
208
  detected_type = _detect_postgresql_type(value)
@@ -188,7 +221,7 @@ def _convert_psqlpy_parameters(value: Any) -> Any:
188
221
 
189
222
 
190
223
  class PsqlpyCursor:
191
- """Context manager for Psqlpy cursor management."""
224
+ """Context manager for psqlpy cursor management."""
192
225
 
193
226
  __slots__ = ("_in_use", "connection")
194
227
 
@@ -197,22 +230,36 @@ class PsqlpyCursor:
197
230
  self._in_use = False
198
231
 
199
232
  async def __aenter__(self) -> "PsqlpyConnection":
200
- """Enter cursor context."""
233
+ """Enter cursor context.
234
+
235
+ Returns:
236
+ Psqlpy connection object
237
+ """
201
238
  self._in_use = True
202
239
  return self.connection
203
240
 
204
241
  async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
205
- """Exit cursor context."""
242
+ """Exit cursor context.
243
+
244
+ Args:
245
+ exc_type: Exception type
246
+ exc_val: Exception value
247
+ exc_tb: Exception traceback
248
+ """
206
249
  _ = (exc_type, exc_val, exc_tb)
207
250
  self._in_use = False
208
251
 
209
252
  def is_in_use(self) -> bool:
210
- """Check if cursor is currently in use."""
253
+ """Check if cursor is currently in use.
254
+
255
+ Returns:
256
+ True if cursor is in use, False otherwise
257
+ """
211
258
  return self._in_use
212
259
 
213
260
 
214
261
  class PsqlpyExceptionHandler:
215
- """Custom async context manager for handling Psqlpy database exceptions."""
262
+ """Async context manager for handling psqlpy database exceptions."""
216
263
 
217
264
  __slots__ = ()
218
265
 
@@ -250,10 +297,10 @@ class PsqlpyExceptionHandler:
250
297
 
251
298
 
252
299
  class PsqlpyDriver(AsyncDriverAdapterBase):
253
- """Psqlpy driver implementation.
300
+ """PostgreSQL driver implementation using psqlpy.
254
301
 
255
- Provides PostgreSQL connectivity through psqlpy with parameter style
256
- conversion, type coercion, error handling, and transaction management.
302
+ Provides parameter style conversion, type coercion, error handling,
303
+ and transaction management.
257
304
  """
258
305
 
259
306
  __slots__ = ()
@@ -277,11 +324,22 @@ class PsqlpyDriver(AsyncDriverAdapterBase):
277
324
  super().__init__(connection=connection, statement_config=statement_config, driver_features=driver_features)
278
325
 
279
326
  def with_cursor(self, connection: "PsqlpyConnection") -> "PsqlpyCursor":
280
- """Create context manager for psqlpy cursor."""
327
+ """Create context manager for psqlpy cursor.
328
+
329
+ Args:
330
+ connection: Psqlpy connection object
331
+
332
+ Returns:
333
+ PsqlpyCursor context manager
334
+ """
281
335
  return PsqlpyCursor(connection)
282
336
 
283
337
  def handle_database_exceptions(self) -> "AbstractAsyncContextManager[None]":
284
- """Handle database-specific exceptions and wrap them appropriately."""
338
+ """Handle database-specific exceptions.
339
+
340
+ Returns:
341
+ Exception handler context manager
342
+ """
285
343
  return PsqlpyExceptionHandler()
286
344
 
287
345
  async def _try_special_handling(self, cursor: "PsqlpyConnection", statement: SQL) -> "Optional[SQLResult]":
@@ -292,13 +350,13 @@ class PsqlpyDriver(AsyncDriverAdapterBase):
292
350
  statement: SQL statement to analyze
293
351
 
294
352
  Returns:
295
- None for standard execution
353
+ SQLResult if special handling applied, None otherwise
296
354
  """
297
355
  _ = (cursor, statement)
298
356
  return None
299
357
 
300
358
  async def _execute_script(self, cursor: "PsqlpyConnection", statement: SQL) -> "ExecutionResult":
301
- """Execute SQL script with statement splitting and parameter handling.
359
+ """Execute SQL script with statement splitting.
302
360
 
303
361
  Args:
304
362
  cursor: Psqlpy connection object
@@ -329,7 +387,7 @@ class PsqlpyDriver(AsyncDriverAdapterBase):
329
387
  )
330
388
 
331
389
  async def _execute_many(self, cursor: "PsqlpyConnection", statement: SQL) -> "ExecutionResult":
332
- """Execute SQL with multiple parameter sets using batch processing.
390
+ """Execute SQL with multiple parameter sets.
333
391
 
334
392
  Args:
335
393
  cursor: Psqlpy connection object
@@ -358,7 +416,7 @@ class PsqlpyDriver(AsyncDriverAdapterBase):
358
416
  return self.create_execution_result(cursor, rowcount_override=rows_affected, is_many_result=True)
359
417
 
360
418
  async def _execute_statement(self, cursor: "PsqlpyConnection", statement: SQL) -> "ExecutionResult":
361
- """Execute single SQL statement with data handling.
419
+ """Execute single SQL statement.
362
420
 
363
421
  Args:
364
422
  cursor: Psqlpy connection object
@@ -396,7 +454,7 @@ class PsqlpyDriver(AsyncDriverAdapterBase):
396
454
  result: Psqlpy execution result object
397
455
 
398
456
  Returns:
399
- Number of rows affected, or -1 if unable to determine
457
+ Number of rows affected, -1 if unable to determine
400
458
  """
401
459
  try:
402
460
  if hasattr(result, "tag") and result.tag:
@@ -416,7 +474,7 @@ class PsqlpyDriver(AsyncDriverAdapterBase):
416
474
  tag: PostgreSQL command tag string
417
475
 
418
476
  Returns:
419
- Number of rows affected, or -1 if unable to parse
477
+ Number of rows affected, -1 if unable to parse
420
478
  """
421
479
  if not tag:
422
480
  return -1
@@ -180,17 +180,11 @@ class PsycopgSyncExceptionHandler:
180
180
  class PsycopgSyncDriver(SyncDriverAdapterBase):
181
181
  """PostgreSQL psycopg synchronous driver.
182
182
 
183
- Provides synchronous database operations for PostgreSQL using psycopg3:
184
- - SQL statement execution with parameter binding
185
- - Transaction management (begin, commit, rollback)
186
- - Result processing with column metadata
187
- - PostgreSQL-specific features support
188
-
189
- PostgreSQL Features:
190
- - Parameter styles ($1, %s, %(name)s)
191
- - PostgreSQL arrays and JSON handling
192
- - COPY operations for bulk data transfer
193
- - PostgreSQL-specific error handling
183
+ Provides synchronous database operations for PostgreSQL using psycopg3.
184
+ Supports SQL statement execution with parameter binding, transaction
185
+ management, result processing with column metadata, parameter style
186
+ conversion, PostgreSQL arrays and JSON handling, COPY operations for
187
+ bulk data transfer, and PostgreSQL-specific error handling.
194
188
  """
195
189
 
196
190
  __slots__ = ()
@@ -486,18 +480,12 @@ class PsycopgAsyncExceptionHandler:
486
480
  class PsycopgAsyncDriver(AsyncDriverAdapterBase):
487
481
  """PostgreSQL psycopg asynchronous driver.
488
482
 
489
- Provides asynchronous database operations for PostgreSQL using psycopg3:
490
- - Async SQL statement execution with parameter binding
491
- - Async transaction management (begin, commit, rollback)
492
- - Async result processing with column metadata
493
- - PostgreSQL-specific features support
494
-
495
- PostgreSQL Features:
496
- - Parameter styles ($1, %s, %(name)s)
497
- - PostgreSQL arrays and JSON handling
498
- - COPY operations for bulk data transfer
499
- - PostgreSQL-specific error handling
500
- - Async pub/sub support (LISTEN/NOTIFY)
483
+ Provides asynchronous database operations for PostgreSQL using psycopg3.
484
+ Supports async SQL statement execution with parameter binding, async
485
+ transaction management, async result processing with column metadata,
486
+ parameter style conversion, PostgreSQL arrays and JSON handling, COPY
487
+ operations for bulk data transfer, PostgreSQL-specific error handling,
488
+ and async pub/sub support.
501
489
  """
502
490
 
503
491
  __slots__ = ()
@@ -50,19 +50,39 @@ sqlite_statement_config = StatementConfig(
50
50
 
51
51
 
52
52
  class SqliteCursor:
53
- """Context manager for SQLite cursor management."""
53
+ """Context manager for SQLite cursor management.
54
+
55
+ Provides automatic cursor creation and cleanup for SQLite database operations.
56
+ """
54
57
 
55
58
  __slots__ = ("connection", "cursor")
56
59
 
57
60
  def __init__(self, connection: "SqliteConnection") -> None:
61
+ """Initialize cursor manager.
62
+
63
+ Args:
64
+ connection: SQLite database connection
65
+ """
58
66
  self.connection = connection
59
67
  self.cursor: Optional[sqlite3.Cursor] = None
60
68
 
61
69
  def __enter__(self) -> "sqlite3.Cursor":
70
+ """Create and return a new cursor.
71
+
72
+ Returns:
73
+ Active SQLite cursor object
74
+ """
62
75
  self.cursor = self.connection.cursor()
63
76
  return self.cursor
64
77
 
65
78
  def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
79
+ """Clean up cursor resources.
80
+
81
+ Args:
82
+ exc_type: Exception type if an exception occurred
83
+ exc_val: Exception value if an exception occurred
84
+ exc_tb: Exception traceback if an exception occurred
85
+ """
66
86
  _ = (exc_type, exc_val, exc_tb)
67
87
  if self.cursor is not None:
68
88
  with contextlib.suppress(Exception):
@@ -70,14 +90,33 @@ class SqliteCursor:
70
90
 
71
91
 
72
92
  class SqliteExceptionHandler:
73
- """Context manager for handling SQLite database exceptions."""
93
+ """Context manager for handling SQLite database exceptions.
94
+
95
+ Catches SQLite-specific exceptions and converts them to appropriate SQLSpec exceptions.
96
+ """
74
97
 
75
98
  __slots__ = ()
76
99
 
77
100
  def __enter__(self) -> None:
78
- return None
101
+ """Enter exception handling context.
102
+
103
+ Returns:
104
+ None
105
+ """
106
+ return
79
107
 
80
108
  def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
109
+ """Handle exceptions and convert to SQLSpec exceptions.
110
+
111
+ Args:
112
+ exc_type: Exception type if an exception occurred
113
+ exc_val: Exception value if an exception occurred
114
+ exc_tb: Exception traceback if an exception occurred
115
+
116
+ Raises:
117
+ SQLSpecError: For general database errors
118
+ SQLParsingError: For SQL syntax or parsing errors
119
+ """
81
120
  if exc_type is None:
82
121
  return
83
122
 
@@ -129,6 +168,13 @@ class SqliteDriver(SyncDriverAdapterBase):
129
168
  statement_config: "Optional[StatementConfig]" = None,
130
169
  driver_features: "Optional[dict[str, Any]]" = None,
131
170
  ) -> None:
171
+ """Initialize SQLite driver.
172
+
173
+ Args:
174
+ connection: SQLite database connection
175
+ statement_config: Statement configuration settings
176
+ driver_features: Driver-specific feature flags
177
+ """
132
178
  if statement_config is None:
133
179
  cache_config = get_cache_config()
134
180
  statement_config = sqlite_statement_config.replace(
@@ -141,11 +187,22 @@ class SqliteDriver(SyncDriverAdapterBase):
141
187
  super().__init__(connection=connection, statement_config=statement_config, driver_features=driver_features)
142
188
 
143
189
  def with_cursor(self, connection: "SqliteConnection") -> "SqliteCursor":
144
- """Create context manager for SQLite cursor."""
190
+ """Create context manager for SQLite cursor.
191
+
192
+ Args:
193
+ connection: SQLite database connection
194
+
195
+ Returns:
196
+ Cursor context manager for safe cursor operations
197
+ """
145
198
  return SqliteCursor(connection)
146
199
 
147
200
  def handle_database_exceptions(self) -> "AbstractContextManager[None]":
148
- """Handle database-specific exceptions and wrap them appropriately."""
201
+ """Handle database-specific exceptions and wrap them appropriately.
202
+
203
+ Returns:
204
+ Context manager that converts SQLite exceptions to SQLSpec exceptions
205
+ """
149
206
  return SqliteExceptionHandler()
150
207
 
151
208
  def _try_special_handling(self, cursor: "sqlite3.Cursor", statement: "SQL") -> "Optional[SQLResult]":
@@ -233,7 +290,11 @@ class SqliteDriver(SyncDriverAdapterBase):
233
290
  return self.create_execution_result(cursor, rowcount_override=affected_rows)
234
291
 
235
292
  def begin(self) -> None:
236
- """Begin a database transaction."""
293
+ """Begin a database transaction.
294
+
295
+ Raises:
296
+ SQLSpecError: If transaction cannot be started
297
+ """
237
298
  try:
238
299
  if not self.connection.in_transaction:
239
300
  self.connection.execute("BEGIN")
@@ -242,7 +303,11 @@ class SqliteDriver(SyncDriverAdapterBase):
242
303
  raise SQLSpecError(msg) from e
243
304
 
244
305
  def rollback(self) -> None:
245
- """Rollback the current transaction."""
306
+ """Rollback the current transaction.
307
+
308
+ Raises:
309
+ SQLSpecError: If transaction cannot be rolled back
310
+ """
246
311
  try:
247
312
  self.connection.rollback()
248
313
  except sqlite3.Error as e:
@@ -250,7 +315,11 @@ class SqliteDriver(SyncDriverAdapterBase):
250
315
  raise SQLSpecError(msg) from e
251
316
 
252
317
  def commit(self) -> None:
253
- """Commit the current transaction."""
318
+ """Commit the current transaction.
319
+
320
+ Raises:
321
+ SQLSpecError: If transaction cannot be committed
322
+ """
254
323
  try:
255
324
  self.connection.commit()
256
325
  except sqlite3.Error as e:
sqlspec/base.py CHANGED
@@ -125,7 +125,7 @@ class SQLSpec:
125
125
  config: The configuration instance to add.
126
126
 
127
127
  Returns:
128
- The type of the added configuration, annotated with its ID for potential use in type systems.
128
+ The type of the added configuration for use as a registry key.
129
129
  """
130
130
  config_type = type(config)
131
131
  if config_type in self._configs:
@@ -331,7 +331,6 @@ class SQLSpec:
331
331
  *args: Positional arguments to pass to the config's provide_connection.
332
332
  **kwargs: Keyword arguments to pass to the config's provide_connection.
333
333
 
334
-
335
334
  Returns:
336
335
  A sync or async context manager yielding a connection.
337
336
  """
@@ -564,12 +563,12 @@ class SQLSpec:
564
563
  """Update cache configuration with partial values.
565
564
 
566
565
  Args:
567
- sql_cache_size: Size of the SQL statement cache
568
- fragment_cache_size: Size of the AST fragment cache
569
- optimized_cache_size: Size of the optimized expression cache
570
- sql_cache_enabled: Enable/disable SQL cache
571
- fragment_cache_enabled: Enable/disable fragment cache
572
- optimized_cache_enabled: Enable/disable optimized cache
566
+ sql_cache_size: Size of the SQL statement cache.
567
+ fragment_cache_size: Size of the AST fragment cache.
568
+ optimized_cache_size: Size of the optimized expression cache.
569
+ sql_cache_enabled: Enable/disable SQL cache.
570
+ fragment_cache_enabled: Enable/disable fragment cache.
571
+ optimized_cache_enabled: Enable/disable optimized cache.
573
572
  """
574
573
  current_config = get_cache_config()
575
574
  update_cache_config(
@@ -593,22 +592,18 @@ class SQLSpec:
593
592
  )
594
593
  )
595
594
 
596
- def _ensure_sql_loader(self) -> "SQLFileLoader":
597
- """Ensure SQL loader is initialized lazily."""
598
- if self._sql_loader is None:
599
- from sqlspec.loader import SQLFileLoader
600
-
601
- self._sql_loader = SQLFileLoader()
602
- return self._sql_loader
603
-
604
595
  def load_sql_files(self, *paths: "Union[str, Path]") -> None:
605
596
  """Load SQL files from paths or directories.
606
597
 
607
598
  Args:
608
599
  *paths: One or more file paths or directory paths to load.
609
600
  """
610
- loader = self._ensure_sql_loader()
611
- loader.load_sql(*paths)
601
+ if self._sql_loader is None:
602
+ from sqlspec.loader import SQLFileLoader
603
+
604
+ self._sql_loader = SQLFileLoader()
605
+
606
+ self._sql_loader.load_sql(*paths)
612
607
  logger.debug("Loaded SQL files: %s", paths)
613
608
 
614
609
  def add_named_sql(self, name: str, sql: str, dialect: "Optional[str]" = None) -> None:
@@ -619,22 +614,30 @@ class SQLSpec:
619
614
  sql: Raw SQL content.
620
615
  dialect: Optional dialect for the SQL statement.
621
616
  """
622
- loader = self._ensure_sql_loader()
623
- loader.add_named_sql(name, sql, dialect)
617
+ if self._sql_loader is None:
618
+ from sqlspec.loader import SQLFileLoader
619
+
620
+ self._sql_loader = SQLFileLoader()
621
+
622
+ self._sql_loader.add_named_sql(name, sql, dialect)
624
623
  logger.debug("Added named SQL: %s", name)
625
624
 
626
625
  def get_sql(self, name: str) -> "SQL":
627
626
  """Get a SQL object by name.
628
627
 
629
628
  Args:
630
- name: Name of the statement (from -- name: in SQL file).
629
+ name: Name of the statement from SQL file comments.
631
630
  Hyphens in names are converted to underscores.
632
631
 
633
632
  Returns:
634
633
  SQL object ready for execution.
635
634
  """
636
- loader = self._ensure_sql_loader()
637
- return loader.get_sql(name)
635
+ if self._sql_loader is None:
636
+ from sqlspec.loader import SQLFileLoader
637
+
638
+ self._sql_loader = SQLFileLoader()
639
+
640
+ return self._sql_loader.get_sql(name)
638
641
 
639
642
  def list_sql_queries(self) -> "list[str]":
640
643
  """List all available query names.
@@ -653,7 +656,7 @@ class SQLSpec:
653
656
  name: Query name to check.
654
657
 
655
658
  Returns:
656
- True if query exists.
659
+ True if the query exists in the loader.
657
660
  """
658
661
  if self._sql_loader is None:
659
662
  return False
@@ -668,7 +671,8 @@ class SQLSpec:
668
671
  def reload_sql_files(self) -> None:
669
672
  """Reload all SQL files.
670
673
 
671
- Note: This clears the cache and requires calling load_sql_files again.
674
+ Note:
675
+ This clears the cache and requires calling load_sql_files again.
672
676
  """
673
677
  if self._sql_loader is not None:
674
678
  self._sql_loader.clear_cache()
@@ -1,6 +1,6 @@
1
1
  """SQL query builders for safe SQL construction.
2
2
 
3
- This package provides fluent interfaces for building SQL queries with
3
+ Provides fluent interfaces for building SQL queries with
4
4
  parameter binding and validation.
5
5
  """
6
6
 
sqlspec/builder/_base.py CHANGED
@@ -1,7 +1,6 @@
1
- """Safe SQL query builder with validation and parameter binding.
1
+ """Base query builder with validation and parameter binding.
2
2
 
3
- This module provides a fluent interface for building SQL queries with
4
- parameter binding and validation.
3
+ Provides abstract base classes and core functionality for SQL query builders.
5
4
  """
6
5
 
7
6
  from abc import ABC, abstractmethod
@@ -31,7 +30,7 @@ logger = get_logger(__name__)
31
30
 
32
31
 
33
32
  class SafeQuery:
34
- """A safely constructed SQL query with bound parameters."""
33
+ """SQL query with bound parameters."""
35
34
 
36
35
  __slots__ = ("dialect", "parameters", "sql")
37
36
 
@@ -44,7 +43,7 @@ class SafeQuery:
44
43
 
45
44
 
46
45
  class QueryBuilder(ABC):
47
- """Abstract base class for SQL query builders with SQLGlot optimization.
46
+ """Abstract base class for SQL query builders.
48
47
 
49
48
  Provides common functionality for dialect handling, parameter management,
50
49
  and query construction using SQLGlot.
@@ -1,7 +1,7 @@
1
- """Pythonic column expressions for query building.
1
+ """Column expressions for query building.
2
2
 
3
- This module provides Column objects that support native Python operators
4
- for building SQL conditions with type safety and parameter binding.
3
+ Provides Column objects that support Python operators for building
4
+ SQL conditions with parameter binding.
5
5
  """
6
6
 
7
7
  from collections.abc import Iterable
sqlspec/builder/_ddl.py CHANGED
@@ -1,4 +1,8 @@
1
- """DDL builders for SQLSpec: DROP, CREATE INDEX, TRUNCATE, etc."""
1
+ """DDL statement builders.
2
+
3
+ Provides builders for DDL operations including CREATE, DROP, ALTER,
4
+ TRUNCATE, and other schema manipulation statements.
5
+ """
2
6
 
3
7
  from typing import TYPE_CHECKING, Any, Optional, Union
4
8
 
@@ -1,7 +1,7 @@
1
- """Safe SQL query builder with validation and parameter binding.
1
+ """DELETE 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 DELETE queries with
4
+ parameter binding and validation.
5
5
  """
6
6
 
7
7
  from typing import Any, Optional
@@ -19,9 +19,8 @@ __all__ = ("Delete",)
19
19
  class Delete(QueryBuilder, WhereClauseMixin, ReturningClauseMixin, DeleteFromClauseMixin):
20
20
  """Builder for DELETE statements.
21
21
 
22
- This builder provides a fluent interface for constructing SQL DELETE statements
23
- with automatic parameter binding and validation. It does not support JOIN
24
- operations to maintain cross-dialect compatibility and safety.
22
+ Constructs SQL DELETE statements with parameter binding and validation.
23
+ Does not support JOIN operations to maintain cross-dialect compatibility.
25
24
  """
26
25
 
27
26
  __slots__ = ("_table",)