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.
- sqlspec/adapters/adbc/driver.py +192 -28
- sqlspec/adapters/asyncmy/driver.py +72 -15
- sqlspec/adapters/asyncpg/config.py +23 -3
- sqlspec/adapters/asyncpg/driver.py +30 -14
- sqlspec/adapters/bigquery/driver.py +79 -9
- sqlspec/adapters/duckdb/driver.py +39 -56
- sqlspec/adapters/oracledb/driver.py +99 -52
- sqlspec/adapters/psqlpy/driver.py +89 -31
- sqlspec/adapters/psycopg/driver.py +11 -23
- sqlspec/adapters/sqlite/driver.py +77 -8
- sqlspec/base.py +29 -25
- sqlspec/builder/__init__.py +1 -1
- sqlspec/builder/_base.py +4 -5
- sqlspec/builder/_column.py +3 -3
- sqlspec/builder/_ddl.py +5 -1
- sqlspec/builder/_delete.py +5 -6
- sqlspec/builder/_insert.py +6 -7
- sqlspec/builder/_merge.py +5 -5
- sqlspec/builder/_parsing_utils.py +3 -3
- sqlspec/builder/_select.py +6 -5
- sqlspec/builder/_update.py +4 -5
- sqlspec/builder/mixins/_cte_and_set_ops.py +5 -1
- sqlspec/builder/mixins/_delete_operations.py +5 -1
- sqlspec/builder/mixins/_insert_operations.py +5 -1
- sqlspec/builder/mixins/_join_operations.py +5 -0
- sqlspec/builder/mixins/_merge_operations.py +5 -1
- sqlspec/builder/mixins/_order_limit_operations.py +5 -1
- sqlspec/builder/mixins/_pivot_operations.py +4 -1
- sqlspec/builder/mixins/_select_operations.py +5 -1
- sqlspec/builder/mixins/_update_operations.py +5 -1
- sqlspec/builder/mixins/_where_clause.py +5 -1
- sqlspec/cli.py +281 -33
- sqlspec/config.py +160 -10
- sqlspec/core/compiler.py +11 -3
- sqlspec/core/filters.py +30 -9
- sqlspec/core/parameters.py +67 -67
- sqlspec/core/result.py +62 -31
- sqlspec/core/splitter.py +160 -34
- sqlspec/core/statement.py +95 -14
- sqlspec/driver/_common.py +12 -3
- sqlspec/driver/mixins/_result_tools.py +21 -4
- sqlspec/driver/mixins/_sql_translator.py +45 -7
- sqlspec/extensions/aiosql/adapter.py +1 -1
- sqlspec/extensions/litestar/_utils.py +1 -1
- sqlspec/extensions/litestar/handlers.py +21 -0
- sqlspec/extensions/litestar/plugin.py +15 -8
- sqlspec/loader.py +12 -12
- sqlspec/migrations/loaders.py +5 -2
- sqlspec/migrations/utils.py +2 -2
- sqlspec/storage/backends/obstore.py +1 -3
- sqlspec/storage/registry.py +1 -1
- sqlspec/utils/__init__.py +7 -0
- sqlspec/utils/deprecation.py +6 -0
- sqlspec/utils/fixtures.py +239 -30
- sqlspec/utils/module_loader.py +5 -1
- sqlspec/utils/serializers.py +6 -0
- sqlspec/utils/singleton.py +6 -0
- sqlspec/utils/sync_tools.py +10 -1
- {sqlspec-0.18.0.dist-info → sqlspec-0.20.0.dist-info}/METADATA +1 -1
- {sqlspec-0.18.0.dist-info → sqlspec-0.20.0.dist-info}/RECORD +64 -64
- {sqlspec-0.18.0.dist-info → sqlspec-0.20.0.dist-info}/WHEEL +0 -0
- {sqlspec-0.18.0.dist-info → sqlspec-0.20.0.dist-info}/entry_points.txt +0 -0
- {sqlspec-0.18.0.dist-info → sqlspec-0.20.0.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.18.0.dist-info → sqlspec-0.20.0.dist-info}/licenses/NOTICE +0 -0
sqlspec/config.py
CHANGED
|
@@ -11,8 +11,11 @@ from sqlspec.utils.logging import get_logger
|
|
|
11
11
|
if TYPE_CHECKING:
|
|
12
12
|
from collections.abc import Awaitable
|
|
13
13
|
from contextlib import AbstractAsyncContextManager, AbstractContextManager
|
|
14
|
+
from pathlib import Path
|
|
14
15
|
|
|
15
16
|
from sqlspec.driver import AsyncDriverAdapterBase, SyncDriverAdapterBase
|
|
17
|
+
from sqlspec.loader import SQLFileLoader
|
|
18
|
+
from sqlspec.migrations.commands import MigrationCommands
|
|
16
19
|
|
|
17
20
|
|
|
18
21
|
__all__ = (
|
|
@@ -45,7 +48,7 @@ logger = get_logger("config")
|
|
|
45
48
|
|
|
46
49
|
|
|
47
50
|
class LifecycleConfig(TypedDict, total=False):
|
|
48
|
-
"""Lifecycle hooks for
|
|
51
|
+
"""Lifecycle hooks for database adapters.
|
|
49
52
|
|
|
50
53
|
Each hook accepts a list of callables to support multiple handlers.
|
|
51
54
|
"""
|
|
@@ -64,7 +67,7 @@ class LifecycleConfig(TypedDict, total=False):
|
|
|
64
67
|
class MigrationConfig(TypedDict, total=False):
|
|
65
68
|
"""Configuration options for database migrations.
|
|
66
69
|
|
|
67
|
-
All fields are optional with
|
|
70
|
+
All fields are optional with default values.
|
|
68
71
|
"""
|
|
69
72
|
|
|
70
73
|
script_location: NotRequired[str]
|
|
@@ -76,11 +79,24 @@ class MigrationConfig(TypedDict, total=False):
|
|
|
76
79
|
project_root: NotRequired[str]
|
|
77
80
|
"""Path to the project root directory. Used for relative path resolution."""
|
|
78
81
|
|
|
82
|
+
enabled: NotRequired[bool]
|
|
83
|
+
"""Whether this configuration should be included in CLI operations. Defaults to True."""
|
|
84
|
+
|
|
79
85
|
|
|
80
86
|
class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
|
|
81
87
|
"""Protocol defining the interface for database configurations."""
|
|
82
88
|
|
|
83
|
-
__slots__ = (
|
|
89
|
+
__slots__ = (
|
|
90
|
+
"_migration_commands",
|
|
91
|
+
"_migration_loader",
|
|
92
|
+
"driver_features",
|
|
93
|
+
"migration_config",
|
|
94
|
+
"pool_instance",
|
|
95
|
+
"statement_config",
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
_migration_loader: "SQLFileLoader"
|
|
99
|
+
_migration_commands: "MigrationCommands"
|
|
84
100
|
driver_type: "ClassVar[type[Any]]"
|
|
85
101
|
connection_type: "ClassVar[type[Any]]"
|
|
86
102
|
is_async: "ClassVar[bool]" = False
|
|
@@ -144,18 +160,148 @@ class DatabaseConfigProtocol(ABC, Generic[ConnectionT, PoolT, DriverT]):
|
|
|
144
160
|
def get_signature_namespace(self) -> "dict[str, type[Any]]":
|
|
145
161
|
"""Get the signature namespace for this database configuration.
|
|
146
162
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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.
|
|
150
166
|
|
|
151
167
|
Returns:
|
|
152
168
|
Dictionary mapping type names to types.
|
|
153
169
|
"""
|
|
154
170
|
return {}
|
|
155
171
|
|
|
172
|
+
def _initialize_migration_components(self) -> None:
|
|
173
|
+
"""Initialize migration loader and commands with necessary imports.
|
|
174
|
+
|
|
175
|
+
Handles the circular import between config and commands by importing
|
|
176
|
+
at runtime when needed.
|
|
177
|
+
"""
|
|
178
|
+
from sqlspec.loader import SQLFileLoader
|
|
179
|
+
from sqlspec.migrations.commands import MigrationCommands
|
|
180
|
+
|
|
181
|
+
self._migration_loader = SQLFileLoader()
|
|
182
|
+
self._migration_commands = MigrationCommands(self) # type: ignore[arg-type]
|
|
183
|
+
|
|
184
|
+
def _ensure_migration_loader(self) -> "SQLFileLoader":
|
|
185
|
+
"""Get the migration SQL loader and auto-load files if needed.
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
SQLFileLoader instance for migration files.
|
|
189
|
+
"""
|
|
190
|
+
# Auto-load migration files from configured migration path if it exists
|
|
191
|
+
migration_config = self.migration_config or {}
|
|
192
|
+
script_location = migration_config.get("script_location", "migrations")
|
|
193
|
+
|
|
194
|
+
from pathlib import Path
|
|
195
|
+
|
|
196
|
+
migration_path = Path(script_location)
|
|
197
|
+
if migration_path.exists() and not self._migration_loader.list_files():
|
|
198
|
+
self._migration_loader.load_sql(migration_path)
|
|
199
|
+
logger.debug("Auto-loaded migration SQL files from %s", migration_path)
|
|
200
|
+
|
|
201
|
+
return self._migration_loader
|
|
202
|
+
|
|
203
|
+
def _ensure_migration_commands(self) -> "MigrationCommands":
|
|
204
|
+
"""Get the migration commands instance.
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
MigrationCommands instance for this config.
|
|
208
|
+
"""
|
|
209
|
+
return self._migration_commands
|
|
210
|
+
|
|
211
|
+
def get_migration_loader(self) -> "SQLFileLoader":
|
|
212
|
+
"""Get the SQL loader for migration files.
|
|
213
|
+
|
|
214
|
+
Provides access to migration SQL files loaded from the configured
|
|
215
|
+
script_location directory. Files are loaded lazily on first access.
|
|
216
|
+
|
|
217
|
+
Returns:
|
|
218
|
+
SQLFileLoader instance with migration files loaded.
|
|
219
|
+
"""
|
|
220
|
+
return self._ensure_migration_loader()
|
|
221
|
+
|
|
222
|
+
def load_migration_sql_files(self, *paths: "Union[str, Path]") -> None:
|
|
223
|
+
"""Load additional migration SQL files from specified paths.
|
|
224
|
+
|
|
225
|
+
Args:
|
|
226
|
+
*paths: One or more file paths or directory paths to load migration SQL files from.
|
|
227
|
+
"""
|
|
228
|
+
from pathlib import Path
|
|
229
|
+
|
|
230
|
+
loader = self._ensure_migration_loader()
|
|
231
|
+
for path in paths:
|
|
232
|
+
path_obj = Path(path)
|
|
233
|
+
if path_obj.exists():
|
|
234
|
+
loader.load_sql(path_obj)
|
|
235
|
+
logger.debug("Loaded migration SQL files from %s", path_obj)
|
|
236
|
+
else:
|
|
237
|
+
logger.warning("Migration path does not exist: %s", path_obj)
|
|
238
|
+
|
|
239
|
+
def get_migration_commands(self) -> "MigrationCommands":
|
|
240
|
+
"""Get migration commands for this configuration.
|
|
241
|
+
|
|
242
|
+
Returns:
|
|
243
|
+
MigrationCommands instance configured for this database.
|
|
244
|
+
"""
|
|
245
|
+
return self._ensure_migration_commands()
|
|
246
|
+
|
|
247
|
+
def migrate_up(self, revision: str = "head") -> None:
|
|
248
|
+
"""Apply migrations up to the specified revision.
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
revision: Target revision or "head" for latest. Defaults to "head".
|
|
252
|
+
"""
|
|
253
|
+
commands = self._ensure_migration_commands()
|
|
254
|
+
commands.upgrade(revision)
|
|
255
|
+
|
|
256
|
+
def migrate_down(self, revision: str = "-1") -> None:
|
|
257
|
+
"""Apply migrations down to the specified revision.
|
|
258
|
+
|
|
259
|
+
Args:
|
|
260
|
+
revision: Target revision, "-1" for one step back, or "base" for all migrations. Defaults to "-1".
|
|
261
|
+
"""
|
|
262
|
+
commands = self._ensure_migration_commands()
|
|
263
|
+
commands.downgrade(revision)
|
|
264
|
+
|
|
265
|
+
def get_current_migration(self, verbose: bool = False) -> "Optional[str]":
|
|
266
|
+
"""Get the current migration version.
|
|
267
|
+
|
|
268
|
+
Args:
|
|
269
|
+
verbose: Whether to show detailed migration history.
|
|
270
|
+
|
|
271
|
+
Returns:
|
|
272
|
+
Current migration version or None if no migrations applied.
|
|
273
|
+
"""
|
|
274
|
+
commands = self._ensure_migration_commands()
|
|
275
|
+
return commands.current(verbose=verbose)
|
|
276
|
+
|
|
277
|
+
def create_migration(self, message: str, file_type: str = "sql") -> None:
|
|
278
|
+
"""Create a new migration file.
|
|
279
|
+
|
|
280
|
+
Args:
|
|
281
|
+
message: Description for the migration.
|
|
282
|
+
file_type: Type of migration file to create ('sql' or 'py'). Defaults to 'sql'.
|
|
283
|
+
"""
|
|
284
|
+
commands = self._ensure_migration_commands()
|
|
285
|
+
commands.revision(message, file_type)
|
|
286
|
+
|
|
287
|
+
def init_migrations(self, directory: "Optional[str]" = None, package: bool = True) -> None:
|
|
288
|
+
"""Initialize migration directory structure.
|
|
289
|
+
|
|
290
|
+
Args:
|
|
291
|
+
directory: Directory to initialize migrations in. Uses script_location from migration_config if not provided.
|
|
292
|
+
package: Whether to create __init__.py file. Defaults to True.
|
|
293
|
+
"""
|
|
294
|
+
if directory is None:
|
|
295
|
+
migration_config = self.migration_config or {}
|
|
296
|
+
directory = migration_config.get("script_location") or "migrations"
|
|
297
|
+
|
|
298
|
+
commands = self._ensure_migration_commands()
|
|
299
|
+
assert directory is not None
|
|
300
|
+
commands.init(directory, package)
|
|
301
|
+
|
|
156
302
|
|
|
157
303
|
class NoPoolSyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
|
|
158
|
-
"""Base class for
|
|
304
|
+
"""Base class for sync database configurations that do not implement a pool."""
|
|
159
305
|
|
|
160
306
|
__slots__ = ("connection_config",)
|
|
161
307
|
is_async: "ClassVar[bool]" = False
|
|
@@ -173,6 +319,7 @@ class NoPoolSyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
|
|
|
173
319
|
self.pool_instance = None
|
|
174
320
|
self.connection_config = connection_config or {}
|
|
175
321
|
self.migration_config: Union[dict[str, Any], MigrationConfig] = migration_config or {}
|
|
322
|
+
self._initialize_migration_components()
|
|
176
323
|
|
|
177
324
|
if statement_config is None:
|
|
178
325
|
default_parameter_config = ParameterStyleConfig(
|
|
@@ -208,7 +355,7 @@ class NoPoolSyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
|
|
|
208
355
|
|
|
209
356
|
|
|
210
357
|
class NoPoolAsyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
|
|
211
|
-
"""Base class for
|
|
358
|
+
"""Base class for async database configurations that do not implement a pool."""
|
|
212
359
|
|
|
213
360
|
__slots__ = ("connection_config",)
|
|
214
361
|
is_async: "ClassVar[bool]" = True
|
|
@@ -226,6 +373,7 @@ class NoPoolAsyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
|
|
|
226
373
|
self.pool_instance = None
|
|
227
374
|
self.connection_config = connection_config or {}
|
|
228
375
|
self.migration_config: Union[dict[str, Any], MigrationConfig] = migration_config or {}
|
|
376
|
+
self._initialize_migration_components()
|
|
229
377
|
|
|
230
378
|
if statement_config is None:
|
|
231
379
|
default_parameter_config = ParameterStyleConfig(
|
|
@@ -261,7 +409,7 @@ class NoPoolAsyncConfig(DatabaseConfigProtocol[ConnectionT, None, DriverT]):
|
|
|
261
409
|
|
|
262
410
|
|
|
263
411
|
class SyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
|
|
264
|
-
"""
|
|
412
|
+
"""Base class for sync database configurations with connection pooling."""
|
|
265
413
|
|
|
266
414
|
__slots__ = ("pool_config",)
|
|
267
415
|
is_async: "ClassVar[bool]" = False
|
|
@@ -280,6 +428,7 @@ class SyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
|
|
|
280
428
|
self.pool_instance = pool_instance
|
|
281
429
|
self.pool_config = pool_config or {}
|
|
282
430
|
self.migration_config: Union[dict[str, Any], MigrationConfig] = migration_config or {}
|
|
431
|
+
self._initialize_migration_components()
|
|
283
432
|
|
|
284
433
|
if statement_config is None:
|
|
285
434
|
default_parameter_config = ParameterStyleConfig(
|
|
@@ -337,7 +486,7 @@ class SyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
|
|
|
337
486
|
|
|
338
487
|
|
|
339
488
|
class AsyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
|
|
340
|
-
"""
|
|
489
|
+
"""Base class for async database configurations with connection pooling."""
|
|
341
490
|
|
|
342
491
|
__slots__ = ("pool_config",)
|
|
343
492
|
is_async: "ClassVar[bool]" = True
|
|
@@ -356,6 +505,7 @@ class AsyncDatabaseConfig(DatabaseConfigProtocol[ConnectionT, PoolT, DriverT]):
|
|
|
356
505
|
self.pool_instance = pool_instance
|
|
357
506
|
self.pool_config = pool_config or {}
|
|
358
507
|
self.migration_config: Union[dict[str, Any], MigrationConfig] = migration_config or {}
|
|
508
|
+
self._initialize_migration_components()
|
|
359
509
|
|
|
360
510
|
if statement_config is None:
|
|
361
511
|
self.statement_config = StatementConfig(
|
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
|
|
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
|
-
"""
|
|
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
|
-
"""
|
|
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
|
-
"""
|
|
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
|
-
"""
|
|
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
|
-
"""
|
|
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
|
-
"""
|
|
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
|
-
"""
|
|
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
|
-
"""
|
|
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
|
-
"""
|
|
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
|
|