sqlspec 0.13.0__py3-none-any.whl → 0.14.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/__init__.py +39 -1
- sqlspec/adapters/adbc/config.py +4 -40
- sqlspec/adapters/adbc/driver.py +29 -16
- sqlspec/adapters/aiosqlite/config.py +15 -20
- sqlspec/adapters/aiosqlite/driver.py +36 -18
- sqlspec/adapters/asyncmy/config.py +16 -33
- sqlspec/adapters/asyncmy/driver.py +23 -16
- sqlspec/adapters/asyncpg/config.py +19 -61
- sqlspec/adapters/asyncpg/driver.py +41 -18
- sqlspec/adapters/bigquery/config.py +2 -43
- sqlspec/adapters/bigquery/driver.py +26 -14
- sqlspec/adapters/duckdb/config.py +2 -49
- sqlspec/adapters/duckdb/driver.py +35 -16
- sqlspec/adapters/oracledb/config.py +30 -83
- sqlspec/adapters/oracledb/driver.py +54 -27
- sqlspec/adapters/psqlpy/config.py +17 -57
- sqlspec/adapters/psqlpy/driver.py +28 -8
- sqlspec/adapters/psycopg/config.py +30 -73
- sqlspec/adapters/psycopg/driver.py +69 -24
- sqlspec/adapters/sqlite/config.py +3 -21
- sqlspec/adapters/sqlite/driver.py +50 -26
- sqlspec/cli.py +248 -0
- sqlspec/config.py +18 -20
- sqlspec/driver/_async.py +28 -10
- sqlspec/driver/_common.py +5 -4
- sqlspec/driver/_sync.py +28 -10
- sqlspec/driver/mixins/__init__.py +6 -0
- sqlspec/driver/mixins/_cache.py +114 -0
- sqlspec/driver/mixins/_pipeline.py +0 -4
- sqlspec/{service/base.py → driver/mixins/_query_tools.py} +86 -421
- sqlspec/driver/mixins/_result_utils.py +0 -2
- sqlspec/driver/mixins/_sql_translator.py +0 -2
- sqlspec/driver/mixins/_storage.py +4 -18
- sqlspec/driver/mixins/_type_coercion.py +0 -2
- sqlspec/driver/parameters.py +4 -4
- sqlspec/extensions/aiosql/adapter.py +4 -4
- sqlspec/extensions/litestar/__init__.py +2 -1
- sqlspec/extensions/litestar/cli.py +48 -0
- sqlspec/extensions/litestar/plugin.py +3 -0
- sqlspec/loader.py +1 -1
- sqlspec/migrations/__init__.py +23 -0
- sqlspec/migrations/base.py +390 -0
- sqlspec/migrations/commands.py +525 -0
- sqlspec/migrations/runner.py +215 -0
- sqlspec/migrations/tracker.py +153 -0
- sqlspec/migrations/utils.py +89 -0
- sqlspec/protocols.py +37 -3
- sqlspec/statement/builder/__init__.py +8 -8
- sqlspec/statement/builder/{column.py → _column.py} +82 -52
- sqlspec/statement/builder/{ddl.py → _ddl.py} +5 -5
- sqlspec/statement/builder/_ddl_utils.py +1 -1
- sqlspec/statement/builder/{delete.py → _delete.py} +1 -1
- sqlspec/statement/builder/{insert.py → _insert.py} +1 -1
- sqlspec/statement/builder/{merge.py → _merge.py} +1 -1
- sqlspec/statement/builder/_parsing_utils.py +5 -3
- sqlspec/statement/builder/{select.py → _select.py} +59 -61
- sqlspec/statement/builder/{update.py → _update.py} +2 -2
- sqlspec/statement/builder/mixins/__init__.py +24 -30
- sqlspec/statement/builder/mixins/{_set_ops.py → _cte_and_set_ops.py} +86 -2
- sqlspec/statement/builder/mixins/{_delete_from.py → _delete_operations.py} +2 -0
- sqlspec/statement/builder/mixins/{_insert_values.py → _insert_operations.py} +70 -1
- sqlspec/statement/builder/mixins/{_merge_clauses.py → _merge_operations.py} +2 -0
- sqlspec/statement/builder/mixins/_order_limit_operations.py +123 -0
- sqlspec/statement/builder/mixins/{_pivot.py → _pivot_operations.py} +71 -2
- sqlspec/statement/builder/mixins/_select_operations.py +612 -0
- sqlspec/statement/builder/mixins/{_update_set.py → _update_operations.py} +73 -2
- sqlspec/statement/builder/mixins/_where_clause.py +536 -0
- sqlspec/statement/cache.py +50 -0
- sqlspec/statement/filters.py +37 -8
- sqlspec/statement/parameters.py +154 -25
- sqlspec/statement/pipelines/__init__.py +1 -1
- sqlspec/statement/pipelines/context.py +4 -4
- sqlspec/statement/pipelines/transformers/_expression_simplifier.py +3 -3
- sqlspec/statement/pipelines/validators/_parameter_style.py +22 -22
- sqlspec/statement/pipelines/validators/_performance.py +1 -5
- sqlspec/statement/sql.py +246 -176
- sqlspec/utils/__init__.py +2 -1
- sqlspec/utils/statement_hashing.py +203 -0
- sqlspec/utils/type_guards.py +32 -0
- {sqlspec-0.13.0.dist-info → sqlspec-0.14.0.dist-info}/METADATA +1 -1
- sqlspec-0.14.0.dist-info/RECORD +143 -0
- sqlspec-0.14.0.dist-info/entry_points.txt +2 -0
- sqlspec/service/__init__.py +0 -4
- sqlspec/service/_util.py +0 -147
- sqlspec/service/pagination.py +0 -26
- sqlspec/statement/builder/mixins/_aggregate_functions.py +0 -250
- sqlspec/statement/builder/mixins/_case_builder.py +0 -91
- sqlspec/statement/builder/mixins/_common_table_expr.py +0 -90
- sqlspec/statement/builder/mixins/_from.py +0 -63
- sqlspec/statement/builder/mixins/_group_by.py +0 -118
- sqlspec/statement/builder/mixins/_having.py +0 -35
- sqlspec/statement/builder/mixins/_insert_from_select.py +0 -47
- sqlspec/statement/builder/mixins/_insert_into.py +0 -36
- sqlspec/statement/builder/mixins/_limit_offset.py +0 -53
- sqlspec/statement/builder/mixins/_order_by.py +0 -46
- sqlspec/statement/builder/mixins/_returning.py +0 -37
- sqlspec/statement/builder/mixins/_select_columns.py +0 -61
- sqlspec/statement/builder/mixins/_unpivot.py +0 -77
- sqlspec/statement/builder/mixins/_update_from.py +0 -55
- sqlspec/statement/builder/mixins/_update_table.py +0 -29
- sqlspec/statement/builder/mixins/_where.py +0 -401
- sqlspec/statement/builder/mixins/_window_functions.py +0 -86
- sqlspec/statement/parameter_manager.py +0 -220
- sqlspec/statement/sql_compiler.py +0 -140
- sqlspec-0.13.0.dist-info/RECORD +0 -150
- /sqlspec/statement/builder/{base.py → _base.py} +0 -0
- /sqlspec/statement/builder/mixins/{_join.py → _join_operations.py} +0 -0
- {sqlspec-0.13.0.dist-info → sqlspec-0.14.0.dist-info}/WHEEL +0 -0
- {sqlspec-0.13.0.dist-info → sqlspec-0.14.0.dist-info}/licenses/LICENSE +0 -0
- {sqlspec-0.13.0.dist-info → sqlspec-0.14.0.dist-info}/licenses/NOTICE +0 -0
sqlspec/utils/__init__.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
from sqlspec.utils import deprecation, fixtures, module_loader, singleton, sync_tools, text
|
|
2
|
+
from sqlspec.utils.statement_hashing import hash_expression
|
|
2
3
|
|
|
3
|
-
__all__ = ("deprecation", "fixtures", "module_loader", "singleton", "sync_tools", "text")
|
|
4
|
+
__all__ = ("deprecation", "fixtures", "hash_expression", "module_loader", "singleton", "sync_tools", "text")
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"""Statement hashing utilities for cache key generation.
|
|
2
|
+
|
|
3
|
+
This module provides centralized hashing logic for SQL statements,
|
|
4
|
+
including expressions, parameters, filters, and complete SQL objects.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
8
|
+
|
|
9
|
+
from sqlglot import exp
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from sqlspec.statement.filters import StatementFilter
|
|
13
|
+
from sqlspec.statement.sql import SQL
|
|
14
|
+
|
|
15
|
+
__all__ = ("hash_expression", "hash_parameters", "hash_sql_statement")
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def hash_expression(expr: Optional[exp.Expression], _seen: Optional[set[int]] = None) -> int:
|
|
19
|
+
"""Generate deterministic hash from AST structure.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
expr: SQLGlot Expression to hash
|
|
23
|
+
_seen: Set of seen object IDs to handle circular references
|
|
24
|
+
|
|
25
|
+
Returns:
|
|
26
|
+
Deterministic hash of the AST structure
|
|
27
|
+
"""
|
|
28
|
+
if expr is None:
|
|
29
|
+
return hash(None)
|
|
30
|
+
|
|
31
|
+
if _seen is None:
|
|
32
|
+
_seen = set()
|
|
33
|
+
|
|
34
|
+
expr_id = id(expr)
|
|
35
|
+
if expr_id in _seen:
|
|
36
|
+
return hash(expr_id)
|
|
37
|
+
|
|
38
|
+
_seen.add(expr_id)
|
|
39
|
+
|
|
40
|
+
# Build hash from type and args
|
|
41
|
+
components: list[Any] = [type(expr).__name__]
|
|
42
|
+
|
|
43
|
+
for key, value in sorted(expr.args.items()):
|
|
44
|
+
components.extend((key, _hash_value(value, _seen)))
|
|
45
|
+
|
|
46
|
+
return hash(tuple(components))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _hash_value(value: Any, _seen: set[int]) -> int:
|
|
50
|
+
"""Hash different value types consistently.
|
|
51
|
+
|
|
52
|
+
Args:
|
|
53
|
+
value: Value to hash (can be Expression, list, dict, or primitive)
|
|
54
|
+
_seen: Set of seen object IDs to handle circular references
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
Deterministic hash of the value
|
|
58
|
+
"""
|
|
59
|
+
if isinstance(value, exp.Expression):
|
|
60
|
+
return hash_expression(value, _seen)
|
|
61
|
+
if isinstance(value, list):
|
|
62
|
+
return hash(tuple(_hash_value(v, _seen) for v in value))
|
|
63
|
+
if isinstance(value, dict):
|
|
64
|
+
items = sorted((k, _hash_value(v, _seen)) for k, v in value.items())
|
|
65
|
+
return hash(tuple(items))
|
|
66
|
+
if isinstance(value, tuple):
|
|
67
|
+
return hash(tuple(_hash_value(v, _seen) for v in value))
|
|
68
|
+
# Primitives: str, int, bool, None, etc.
|
|
69
|
+
return hash(value)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def hash_parameters(
|
|
73
|
+
positional_params: Optional[list[Any]] = None,
|
|
74
|
+
named_params: Optional[dict[str, Any]] = None,
|
|
75
|
+
original_parameters: Optional[Any] = None,
|
|
76
|
+
) -> int:
|
|
77
|
+
"""Generate hash for SQL parameters.
|
|
78
|
+
|
|
79
|
+
Args:
|
|
80
|
+
positional_params: List of positional parameters
|
|
81
|
+
named_params: Dictionary of named parameters
|
|
82
|
+
original_parameters: Original parameters (for execute_many)
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
Combined hash of all parameters
|
|
86
|
+
"""
|
|
87
|
+
param_hash = 0
|
|
88
|
+
|
|
89
|
+
# Hash positional parameters
|
|
90
|
+
if positional_params:
|
|
91
|
+
# Handle unhashable types like lists
|
|
92
|
+
hashable_params = []
|
|
93
|
+
for param in positional_params:
|
|
94
|
+
if isinstance(param, (list, dict)):
|
|
95
|
+
# Convert unhashable types to hashable representations
|
|
96
|
+
hashable_params.append(repr(param))
|
|
97
|
+
else:
|
|
98
|
+
hashable_params.append(param)
|
|
99
|
+
param_hash ^= hash(tuple(hashable_params))
|
|
100
|
+
|
|
101
|
+
# Hash named parameters
|
|
102
|
+
if named_params:
|
|
103
|
+
# Handle unhashable types in named params
|
|
104
|
+
hashable_items = []
|
|
105
|
+
for key, value in sorted(named_params.items()):
|
|
106
|
+
if isinstance(value, (list, dict)):
|
|
107
|
+
hashable_items.append((key, repr(value)))
|
|
108
|
+
else:
|
|
109
|
+
hashable_items.append((key, value))
|
|
110
|
+
param_hash ^= hash(tuple(hashable_items))
|
|
111
|
+
|
|
112
|
+
# Hash original parameters (important for execute_many)
|
|
113
|
+
if original_parameters is not None:
|
|
114
|
+
if isinstance(original_parameters, list):
|
|
115
|
+
# For execute_many, hash the count and first few items to avoid
|
|
116
|
+
# performance issues with large parameter sets
|
|
117
|
+
param_hash ^= hash(("original_count", len(original_parameters)))
|
|
118
|
+
if original_parameters:
|
|
119
|
+
# Hash first 3 items as representatives
|
|
120
|
+
sample_size = min(3, len(original_parameters))
|
|
121
|
+
sample_hash = hash(repr(original_parameters[:sample_size]))
|
|
122
|
+
param_hash ^= hash(("original_sample", sample_hash))
|
|
123
|
+
else:
|
|
124
|
+
param_hash ^= hash(("original", repr(original_parameters)))
|
|
125
|
+
|
|
126
|
+
return param_hash
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def hash_filters(filters: Optional[list["StatementFilter"]] = None) -> int:
|
|
130
|
+
"""Generate hash for statement filters.
|
|
131
|
+
|
|
132
|
+
Args:
|
|
133
|
+
filters: List of statement filters
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
Hash of the filters
|
|
137
|
+
"""
|
|
138
|
+
if not filters:
|
|
139
|
+
return 0
|
|
140
|
+
|
|
141
|
+
# Use class names and any hashable attributes
|
|
142
|
+
filter_components = []
|
|
143
|
+
for f in filters:
|
|
144
|
+
# Use class name as primary identifier
|
|
145
|
+
components: list[Any] = [f.__class__.__name__]
|
|
146
|
+
|
|
147
|
+
# Add any hashable attributes if available
|
|
148
|
+
if hasattr(f, "__dict__"):
|
|
149
|
+
for key, value in sorted(f.__dict__.items()):
|
|
150
|
+
try:
|
|
151
|
+
# Try to hash the value
|
|
152
|
+
hash(value)
|
|
153
|
+
components.append((key, value))
|
|
154
|
+
except TypeError: # noqa: PERF203
|
|
155
|
+
# If not hashable, use repr
|
|
156
|
+
components.append((key, repr(value)))
|
|
157
|
+
|
|
158
|
+
filter_components.append(tuple(components))
|
|
159
|
+
|
|
160
|
+
return hash(tuple(filter_components))
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def hash_sql_statement(statement: "SQL") -> str:
|
|
164
|
+
"""Generate a complete cache key for a SQL statement.
|
|
165
|
+
|
|
166
|
+
This centralizes all the complex hashing logic that was previously
|
|
167
|
+
scattered across different parts of the codebase.
|
|
168
|
+
|
|
169
|
+
Args:
|
|
170
|
+
statement: SQL statement object
|
|
171
|
+
|
|
172
|
+
Returns:
|
|
173
|
+
Cache key string
|
|
174
|
+
"""
|
|
175
|
+
from sqlspec.utils.type_guards import is_expression
|
|
176
|
+
|
|
177
|
+
# Hash the expression or raw SQL
|
|
178
|
+
if is_expression(statement._statement):
|
|
179
|
+
expr_hash = hash_expression(statement._statement)
|
|
180
|
+
else:
|
|
181
|
+
expr_hash = hash(statement._raw_sql)
|
|
182
|
+
|
|
183
|
+
# Hash all parameters
|
|
184
|
+
param_hash = hash_parameters(
|
|
185
|
+
positional_params=statement._positional_params,
|
|
186
|
+
named_params=statement._named_params,
|
|
187
|
+
original_parameters=statement._original_parameters,
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
# Hash filters
|
|
191
|
+
filter_hash = hash_filters(statement._filters)
|
|
192
|
+
|
|
193
|
+
# Combine with other state
|
|
194
|
+
state_components = [
|
|
195
|
+
expr_hash,
|
|
196
|
+
param_hash,
|
|
197
|
+
filter_hash,
|
|
198
|
+
hash(statement._dialect), # Use _dialect instead of _config.dialect
|
|
199
|
+
hash(statement._is_many),
|
|
200
|
+
hash(statement._is_script),
|
|
201
|
+
]
|
|
202
|
+
|
|
203
|
+
return f"sql:{hash(tuple(state_components))}"
|
sqlspec/utils/type_guards.py
CHANGED
|
@@ -69,11 +69,15 @@ __all__ = (
|
|
|
69
69
|
"extract_dataclass_items",
|
|
70
70
|
"has_bytes_conversion",
|
|
71
71
|
"has_dict_attribute",
|
|
72
|
+
"has_expression_attr",
|
|
72
73
|
"has_expressions",
|
|
74
|
+
"has_parameter_builder",
|
|
73
75
|
"has_parameter_value",
|
|
74
76
|
"has_query_builder_parameters",
|
|
75
77
|
"has_risk_level",
|
|
76
78
|
"has_sql_method",
|
|
79
|
+
"has_sqlglot_expression",
|
|
80
|
+
"has_to_statement",
|
|
77
81
|
"has_with_method",
|
|
78
82
|
"is_async_closeable_connection",
|
|
79
83
|
"is_async_copy_capable",
|
|
@@ -890,3 +894,31 @@ def is_object_store_item(obj: Any) -> "TypeGuard[ObjectStoreItemProtocol]":
|
|
|
890
894
|
from sqlspec.protocols import ObjectStoreItemProtocol
|
|
891
895
|
|
|
892
896
|
return isinstance(obj, ObjectStoreItemProtocol)
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
def has_sqlglot_expression(obj: Any) -> "TypeGuard[Any]":
|
|
900
|
+
"""Check if an object has a sqlglot_expression property."""
|
|
901
|
+
from sqlspec.protocols import HasSQLGlotExpressionProtocol
|
|
902
|
+
|
|
903
|
+
return isinstance(obj, HasSQLGlotExpressionProtocol)
|
|
904
|
+
|
|
905
|
+
|
|
906
|
+
def has_parameter_builder(obj: Any) -> "TypeGuard[Any]":
|
|
907
|
+
"""Check if an object has an add_parameter method."""
|
|
908
|
+
from sqlspec.protocols import HasParameterBuilderProtocol
|
|
909
|
+
|
|
910
|
+
return isinstance(obj, HasParameterBuilderProtocol)
|
|
911
|
+
|
|
912
|
+
|
|
913
|
+
def has_expression_attr(obj: Any) -> "TypeGuard[Any]":
|
|
914
|
+
"""Check if an object has an _expression attribute."""
|
|
915
|
+
from sqlspec.protocols import HasExpressionProtocol
|
|
916
|
+
|
|
917
|
+
return isinstance(obj, HasExpressionProtocol)
|
|
918
|
+
|
|
919
|
+
|
|
920
|
+
def has_to_statement(obj: Any) -> "TypeGuard[Any]":
|
|
921
|
+
"""Check if an object has a to_statement method."""
|
|
922
|
+
from sqlspec.protocols import HasToStatementProtocol
|
|
923
|
+
|
|
924
|
+
return isinstance(obj, HasToStatementProtocol)
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
sqlspec/__init__.py,sha256=SEPpbVPjSiF9kS4FpowO7S0jm8YNMD9FiX-5lrrCbY0,1676
|
|
2
|
+
sqlspec/__metadata__.py,sha256=hNP3wXvtk8fQVPKGjRLpZ9mP-gaPJqzrmgm3UqpDIXQ,460
|
|
3
|
+
sqlspec/_serialization.py,sha256=7zox4G9zIps-DCdIEwYs4gwALfEOy1g_sWS4r5kpzO8,2604
|
|
4
|
+
sqlspec/_sql.py,sha256=zqMtVWBZzbnNErB8VyJkjDCPq0RNkhGUPA2ZCOtzmGo,35759
|
|
5
|
+
sqlspec/_typing.py,sha256=Vn1CTCfedAHZV3pKZP-l_mPw9pTxesCzRKVRypzNY_k,17903
|
|
6
|
+
sqlspec/base.py,sha256=a7adbCUzohf1MU-iP0TxazGsk9fsJhJmxuFKNWkgC6o,18355
|
|
7
|
+
sqlspec/cli.py,sha256=V8dYi286yXsrZg-w8vsh9OWKngViYCQJejujLjoV5co,9980
|
|
8
|
+
sqlspec/config.py,sha256=IfjXcHFXmGseUcMsf4eEHgeh7oOc2EEIg34R7BC62UI,13144
|
|
9
|
+
sqlspec/exceptions.py,sha256=T2h-tCN05sRKSpXDjPtYXvNgwInNVzTpha1PIkSUROQ,14168
|
|
10
|
+
sqlspec/loader.py,sha256=sR8hSbxbuo3QFC0YoIaT9Xf05QNqtG_WX912IG56kas,15353
|
|
11
|
+
sqlspec/protocols.py,sha256=Uum9tliNG6MOcXBK6KRBmkWGikhEAzH2qIAgZITXd1U,18094
|
|
12
|
+
sqlspec/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
|
+
sqlspec/typing.py,sha256=qkUcvruNzRUUfpv4AkbQezpy9SokhVHXlMbfFNwQlnU,8721
|
|
14
|
+
sqlspec/adapters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
+
sqlspec/adapters/adbc/__init__.py,sha256=v9bs7501PgEyzR1XIsEpE2Wdrj9DOYkZ4grysw72UXk,218
|
|
16
|
+
sqlspec/adapters/adbc/config.py,sha256=pOtwsbXp6LsKiMVFDdOf6aBNSkxxqH1JyAyLE02C1Wg,19221
|
|
17
|
+
sqlspec/adapters/adbc/driver.py,sha256=JWfLd2Pl6Sa1mO2gx-Vv-AC2h0aRxDs0L8yCBAJkSMY,17207
|
|
18
|
+
sqlspec/adapters/aiosqlite/__init__.py,sha256=7wPmhXQeu4jRi-LZzPxAPTdgRmgmyqCn9U-4wnCWoLM,258
|
|
19
|
+
sqlspec/adapters/aiosqlite/config.py,sha256=Rg2RduE5wLM7JkEITtQg6kJQ2n6YVgKsl0S-io-18n0,7246
|
|
20
|
+
sqlspec/adapters/aiosqlite/driver.py,sha256=40c3YVO9UcnUDSlqwEpuI2CNMzsufR4WVGeUKBMcnMY,12176
|
|
21
|
+
sqlspec/adapters/asyncmy/__init__.py,sha256=zYpebEt_PrNCifLcqXiCcWVm0Zl-LvWbFDromWwSTw8,270
|
|
22
|
+
sqlspec/adapters/asyncmy/config.py,sha256=jYeF80DKdd5arS4kSPz4hcpLnzv1WgQa5s9DmEy02OU,10155
|
|
23
|
+
sqlspec/adapters/asyncmy/driver.py,sha256=-rZcBj-gbJ6r3qZQzltqfOHyA70iSg9r4XtieuLliGg,10571
|
|
24
|
+
sqlspec/adapters/asyncpg/__init__.py,sha256=svnbKlOin8jRL88AdAqflBEU-WEAzp0Thc2y50QsxIo,310
|
|
25
|
+
sqlspec/adapters/asyncpg/config.py,sha256=8fKZ55YynepP7eC6A0Z3jpXcGVoSuLW9yGUH04O2a4A,11857
|
|
26
|
+
sqlspec/adapters/asyncpg/driver.py,sha256=sfoxCkHzJvRuE5kNRUH--zCecf2kcqNnDz9OIYsLv54,18629
|
|
27
|
+
sqlspec/adapters/bigquery/__init__.py,sha256=fWRH-BoCNX4rYwhU2DK64cXWpfkYpWIExddJAti0bxM,250
|
|
28
|
+
sqlspec/adapters/bigquery/config.py,sha256=z6FFWUvk3AdXcPRmOYf1lg-UlBqCq8EEDcxDz8-lI0Y,15773
|
|
29
|
+
sqlspec/adapters/bigquery/driver.py,sha256=zUZGGOuzQ4M4Ekt0H59UUQvX8AT4i-YUalkp2Ql6lKo,30956
|
|
30
|
+
sqlspec/adapters/duckdb/__init__.py,sha256=I1f6szfpKKrq6WhyDoUXD3i3NN4yjsh94_fhP1URI5M,351
|
|
31
|
+
sqlspec/adapters/duckdb/config.py,sha256=5k2fgJN1yTZuq4I0VRyIaiMno507sd6R_sl5G8sgpsI,18974
|
|
32
|
+
sqlspec/adapters/duckdb/driver.py,sha256=499tJ9xLj_09MDmnhuGHPiknzT7OFhCmorxB1yHXvXs,19051
|
|
33
|
+
sqlspec/adapters/oracledb/__init__.py,sha256=nn3whn0UyBThoXnE1-5_byVuc9PJjvB2P896p7LpNZI,474
|
|
34
|
+
sqlspec/adapters/oracledb/config.py,sha256=IRIwiWOo0BWoilGxtkrGNZEzVc8o8JqBQXSWdQoKgK8,22017
|
|
35
|
+
sqlspec/adapters/oracledb/driver.py,sha256=S7AyrOk1YbtGsdwrRJJi9-iI2hsBBE8rE67Tlw2kXMY,25790
|
|
36
|
+
sqlspec/adapters/psqlpy/__init__.py,sha256=dp0-96V4SAbNEvOqlJ8PWEyJMYzZGElVoyneZqJ-fbQ,297
|
|
37
|
+
sqlspec/adapters/psqlpy/config.py,sha256=7sM-RGEVpkJLHrX7DemlreL7spJdcrVZ0dDQSMDyt4k,15309
|
|
38
|
+
sqlspec/adapters/psqlpy/driver.py,sha256=GifEdVZKgqKaN0pajWCpZVvW0bKNRXeMZUhcNu-tetQ,10839
|
|
39
|
+
sqlspec/adapters/psycopg/__init__.py,sha256=ukkCUPrJPyAG78v4rOqcK4WZDs26PeB9Ra9qkFrGJ3E,484
|
|
40
|
+
sqlspec/adapters/psycopg/config.py,sha256=PAKtLZHQjGI3oCzoUL5jd0pNrOEdFTtRPsr9-kRmiqo,26300
|
|
41
|
+
sqlspec/adapters/psycopg/driver.py,sha256=lFoqYgG19lAA32_zjkx2yzYosBoINdnWG20KLDz2a3Q,42123
|
|
42
|
+
sqlspec/adapters/sqlite/__init__.py,sha256=1lYrJ-DojUAOvXMoZRUJNEVyMmYhO41hMJnDWCEeXlw,234
|
|
43
|
+
sqlspec/adapters/sqlite/config.py,sha256=ab9gYZvisBMO-lcB93ufmNn8lajs0-ZnFSrCtghWXPY,5757
|
|
44
|
+
sqlspec/adapters/sqlite/driver.py,sha256=Joov0hv709BrkNFFEyBC8saa3MgAM8uW0Du-kQxXedk,13343
|
|
45
|
+
sqlspec/driver/__init__.py,sha256=0udRS5IlJ17HzOCvzapG8c_88yAwTQri1XLD_3fZxZU,671
|
|
46
|
+
sqlspec/driver/_async.py,sha256=UYNjJ70kcIeRWfMBfXqBeVhtqGP9QhmANT2bR2VkRH8,10594
|
|
47
|
+
sqlspec/driver/_common.py,sha256=ohRsk4RmwHO0qLuDbjUpbXB9URC5CWrUOE-lSkFW5JI,15831
|
|
48
|
+
sqlspec/driver/_sync.py,sha256=yivXeRRIFpWkS62Kbi-pRDYidhh3epdJTbjqhLxwFNo,10434
|
|
49
|
+
sqlspec/driver/connection.py,sha256=zKP2p-VLxN07IPfOIBKMRELHN7ZMjmRVUKBgSW-6RQg,6610
|
|
50
|
+
sqlspec/driver/parameters.py,sha256=hxS3K6oICM8mtvRI3429jHPlJJL524b26wU3XFiFlKA,3995
|
|
51
|
+
sqlspec/driver/mixins/__init__.py,sha256=fvzM9gVjjnfUUTZ1TaDv-tEnxS1X-lxYiH7kZvBptzk,922
|
|
52
|
+
sqlspec/driver/mixins/_cache.py,sha256=GmQZLId_RdJX9BpEnVgWYWVmii3yjqGdnA6p1yawo08,3990
|
|
53
|
+
sqlspec/driver/mixins/_csv_writer.py,sha256=-uRe7QZRWtdZTFG3Fiej4Ia8EyQcjYr7oPT6wb0qTOc,2716
|
|
54
|
+
sqlspec/driver/mixins/_pipeline.py,sha256=71OyeDxAQc7KNGFqObMYUU_4LBCMvsm0qCZDiHEDwOI,19548
|
|
55
|
+
sqlspec/driver/mixins/_query_tools.py,sha256=c12s9gmOhAmgvIbK301SllOz89svgOXau5PwwnNu_TY,29186
|
|
56
|
+
sqlspec/driver/mixins/_result_utils.py,sha256=JzMpBXLxn9POMUnqaShhU1qc8TlHwCEy8H5vqnpNnXE,5672
|
|
57
|
+
sqlspec/driver/mixins/_sql_translator.py,sha256=wMv8FtGmulewCTFMdiQhlkiTz8hf7PKy_8VKP55aTuU,1499
|
|
58
|
+
sqlspec/driver/mixins/_storage.py,sha256=YNpkp_ZLXCIwJjosaUJXEFHhi8QGtgP1lKKop_YSWPc,38120
|
|
59
|
+
sqlspec/driver/mixins/_type_coercion.py,sha256=Al5IhsYzCnauOYW9o-STZ9DbIi9u8qYHJDeNDppN5q4,4558
|
|
60
|
+
sqlspec/extensions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
61
|
+
sqlspec/extensions/aiosql/__init__.py,sha256=-9cefc9pYPf9vCgALoB-y1DtmcgRjKe2azfl6RIarAA,414
|
|
62
|
+
sqlspec/extensions/aiosql/adapter.py,sha256=jLOMftHnUR42khs63aYFS2TYa6udUPf4WrYbgHoUajg,16522
|
|
63
|
+
sqlspec/extensions/litestar/__init__.py,sha256=tOmQ7RHSWOot7p30gk0efxxuP0OCq1opyyZqNmQY7FE,320
|
|
64
|
+
sqlspec/extensions/litestar/_utils.py,sha256=o-FuUj1_WkDrLxQxiP6hXDak66XfyRP3QLyEVKrIRjI,1954
|
|
65
|
+
sqlspec/extensions/litestar/cli.py,sha256=NYjPIWe0jESBgS0AG-3bdpcC5YM4RmZeeeTeFQK5Yqo,1362
|
|
66
|
+
sqlspec/extensions/litestar/config.py,sha256=vLXM425tCV3IbJiNO1ZG90ctjBTb9oQCuLsqCaUYmo8,4685
|
|
67
|
+
sqlspec/extensions/litestar/handlers.py,sha256=bVoWmHhCsHZkXZXYHE23yDaJlRoydfvU-boJjA3BSLE,10478
|
|
68
|
+
sqlspec/extensions/litestar/plugin.py,sha256=SCkO6_dq6fiISXzNWqQTinbNayCMqzQ33EU9QhMWyAg,5539
|
|
69
|
+
sqlspec/extensions/litestar/providers.py,sha256=wUGqPeNV58rPqL1iwDQg439C4y-Zg-eXEogjeFsv0iQ,21021
|
|
70
|
+
sqlspec/migrations/__init__.py,sha256=-Shsli3g2C7e8adYVrOwBskTb7iESiAy4NChvcueZkY,776
|
|
71
|
+
sqlspec/migrations/base.py,sha256=kvv_Vi4-ZV4_HY0Ug2cZdL3V7bkMSCKyzqus3kOyKyo,11894
|
|
72
|
+
sqlspec/migrations/commands.py,sha256=1Q_rO21uruurAdAxtw81PkH28iUSmay1Zi87kSYwRRY,19672
|
|
73
|
+
sqlspec/migrations/runner.py,sha256=CH9zh-BurgkgmSXU-dHdzl0Y1JqWfWJuYJ7SUtW89_0,6893
|
|
74
|
+
sqlspec/migrations/tracker.py,sha256=CLsqb6dy34WMvkhvKVBkj8s07FhAnWsgQ77k16bz_s4,5412
|
|
75
|
+
sqlspec/migrations/utils.py,sha256=NKyJbfHlcCMfzJzuQc9pItvoYPt4lG-mG8u4oBmLo6o,2614
|
|
76
|
+
sqlspec/statement/__init__.py,sha256=NDvdrpr1EqAZXp4HmhTVaRnWVscahPSHpmSO8DHSoMY,536
|
|
77
|
+
sqlspec/statement/cache.py,sha256=eS0vi5icd2TWOF1bFL2XKemF0NBW2dKMHNqSCCtwiF0,1387
|
|
78
|
+
sqlspec/statement/filters.py,sha256=CmgGtQ7W5gJHnskpWXXJ7jdVmtoEGioHRTPntAEil2E,23478
|
|
79
|
+
sqlspec/statement/parameters.py,sha256=YbXs6f9p4TaNR7ebjfXAqKob5a_u3AvNBK5OtgjVtpA,41248
|
|
80
|
+
sqlspec/statement/result.py,sha256=-yARFxg7Wsm8nAeHMpnJ58OLd2VujFiZx29wfo7eFVs,14514
|
|
81
|
+
sqlspec/statement/splitter.py,sha256=mCzJsNEtJFk4A0FdTELkG_qOggRFCQC_ZEJisVo9orY,24111
|
|
82
|
+
sqlspec/statement/sql.py,sha256=bfBSp7xzrt3_RM9CvpeGJ2uBipmZ0Od5SM2cYQGV814,75761
|
|
83
|
+
sqlspec/statement/builder/__init__.py,sha256=sDC8HQ-LnfqzF-XmTT0YErp8wTaJiIu5YP3pdhb2MgY,1618
|
|
84
|
+
sqlspec/statement/builder/_base.py,sha256=DArCuNwDXslt73Jk5Io3WqUP1ZXA0e4cUXtzFjvQ5g4,14738
|
|
85
|
+
sqlspec/statement/builder/_column.py,sha256=0yTC00IMRVVuOXYXdz2Uy7BmtLe48apIY1N6oSUbp0s,12918
|
|
86
|
+
sqlspec/statement/builder/_ddl.py,sha256=6VfhavHfS4vONRPXvQl2TohizhJNGUTwWGnN9XWqT1o,51521
|
|
87
|
+
sqlspec/statement/builder/_ddl_utils.py,sha256=6BEcVuSAt0mHPuT8QZQJapWorPxgMzaEX0PxKeYxMQg,4327
|
|
88
|
+
sqlspec/statement/builder/_delete.py,sha256=fDuLaQIcYAJEZrQ0tdnuSmo2DcbHPiOej_YceOBKI1c,2882
|
|
89
|
+
sqlspec/statement/builder/_insert.py,sha256=6LARJr81LAR418DNlzsy8qPErER14a-Dy0Cs9UZK20w,10130
|
|
90
|
+
sqlspec/statement/builder/_merge.py,sha256=xjyKDqU7ABb0gA6vMoQXJGTPsUkk1j6Siohj9wHWGaE,2784
|
|
91
|
+
sqlspec/statement/builder/_parsing_utils.py,sha256=dxvbSkYMAHbHJx3nMU_4S2baEJ6Vp1TIJpl7BehAlpY,5841
|
|
92
|
+
sqlspec/statement/builder/_select.py,sha256=RSVTloFC7v0KYcc-zrToLiZTmO8D18hCZQ1UCs4e4NU,8527
|
|
93
|
+
sqlspec/statement/builder/_update.py,sha256=d-epAsZn3HKU_QNWIP6X6dlXZTokSwLRMbN86pFyN_8,6247
|
|
94
|
+
sqlspec/statement/builder/mixins/__init__.py,sha256=W5xXHE315-vAg76gbRBsQmYu72XY7wZ2vTbXM1xR_tk,2002
|
|
95
|
+
sqlspec/statement/builder/mixins/_cte_and_set_ops.py,sha256=VH7a6rZ29C7z30z_z-joRu2XVP4jsNqtQzHpYyfQ2w0,8911
|
|
96
|
+
sqlspec/statement/builder/mixins/_delete_operations.py,sha256=0f8ZZMFx5b53EUx1oF264owLb6aWP45naeB6g-BZQys,1068
|
|
97
|
+
sqlspec/statement/builder/mixins/_insert_operations.py,sha256=93kVOOCZBxMAN0uILNejFYIDrBg04NsPIvz-cTTGKzA,5415
|
|
98
|
+
sqlspec/statement/builder/mixins/_join_operations.py,sha256=lSGFtq_KJ985SCmUKmIx-4NwniIwQIVmLJYryF5mtc4,5658
|
|
99
|
+
sqlspec/statement/builder/mixins/_merge_operations.py,sha256=RrjyueCzxOhqyJSrJQlL89LkJyKES2-kMsfKy-w89XQ,16846
|
|
100
|
+
sqlspec/statement/builder/mixins/_order_limit_operations.py,sha256=7UOvQrRwTnOpBAXTGV509aqNj63J5UhuMIHYBjLh8vE,4538
|
|
101
|
+
sqlspec/statement/builder/mixins/_pivot_operations.py,sha256=yyKxBHaw9ApO4mwALo3ulohT08Z3kh07Mtst4DMULk4,6181
|
|
102
|
+
sqlspec/statement/builder/mixins/_select_operations.py,sha256=WM_wZPdKy8m-kAlfrMECFX1c2U5sZk-qRH_pTAMlUW4,25433
|
|
103
|
+
sqlspec/statement/builder/mixins/_update_operations.py,sha256=h9yMqIfLJvZlv8uJBZktqT3pJyu62DxPKffSedS0NuI,7508
|
|
104
|
+
sqlspec/statement/builder/mixins/_where_clause.py,sha256=yBRXq0pPMJKvpbaGI0FLZQNE2gw9ND_wofXTnsSXtZw,27018
|
|
105
|
+
sqlspec/statement/pipelines/__init__.py,sha256=aN8GtpqtjTKALANNm8KH5Adq9ijP1_Kq_I9s0S7t0QI,7343
|
|
106
|
+
sqlspec/statement/pipelines/context.py,sha256=9BLM61deXviucJ45xBDmQZg5bpkQ02tHCMRyQNq2YQQ,4219
|
|
107
|
+
sqlspec/statement/pipelines/analyzers/__init__.py,sha256=RY7W0AiWG-8qdrTmRSGlEofjrPPJCJUnNK-LRukKt5Q,330
|
|
108
|
+
sqlspec/statement/pipelines/analyzers/_analyzer.py,sha256=0_FDty6H_4JvQwee_NrzmptX9-VdhyAePXUstuq4MU4,27474
|
|
109
|
+
sqlspec/statement/pipelines/transformers/__init__.py,sha256=Kh4CE_izdwEsSF7Is6_6NXqtNmbLm5x5OWdnlUGp9ok,480
|
|
110
|
+
sqlspec/statement/pipelines/transformers/_expression_simplifier.py,sha256=-imYcKeYcE66Uj04k-QywCcjvuZmvha_2H6rTy7wdSo,3376
|
|
111
|
+
sqlspec/statement/pipelines/transformers/_literal_parameterizer.py,sha256=N6a2lMGBHXcoHuSySY_9JhObNkPWabUBpR_25ZCnv0w,57183
|
|
112
|
+
sqlspec/statement/pipelines/transformers/_remove_comments_and_hints.py,sha256=-gM6VnlhNtQzSbQq44hQ5mhaPqNsjzeCaTgXTycgkOk,3008
|
|
113
|
+
sqlspec/statement/pipelines/validators/__init__.py,sha256=cdlwdLhOT2OwTbueIsA7bfRG2b6y-j7dw9pMzl5AP0M,747
|
|
114
|
+
sqlspec/statement/pipelines/validators/_dml_safety.py,sha256=s7Eee60u6w0K35vz4GVAwsB5Xy8zUqWhiIx_pRVfERo,10585
|
|
115
|
+
sqlspec/statement/pipelines/validators/_parameter_style.py,sha256=Dj85rkH1GyO4dRDgix-4CR9i3sTN_dO4pfmnIe8ORmg,17810
|
|
116
|
+
sqlspec/statement/pipelines/validators/_performance.py,sha256=HjXi24xh5jAHoP-tRZisu21E6ZnE1il4nQOMgRc80qo,26275
|
|
117
|
+
sqlspec/statement/pipelines/validators/_security.py,sha256=3WuH9n4j-VKOgmQnZvFIoI4MieRBVShtOZvXl2SJsyk,42103
|
|
118
|
+
sqlspec/storage/__init__.py,sha256=ZS8rmhN8e_h_df-Oab64Jh4EbddElBbmrtHkuO-KqOE,703
|
|
119
|
+
sqlspec/storage/capabilities.py,sha256=fsnQ9jbjHBFvd3P9yWAzfjPpVYUGcsTtR6fm5iOCvXY,3054
|
|
120
|
+
sqlspec/storage/registry.py,sha256=lv9pGt6vt0tDNAlao9qA7rSsFsCZtaOr48aG15IoMFA,10976
|
|
121
|
+
sqlspec/storage/backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
122
|
+
sqlspec/storage/backends/base.py,sha256=34XYQuz1tQ-q_ZZwOz-Kimgvl088SR3VUYJoA-STslc,6350
|
|
123
|
+
sqlspec/storage/backends/fsspec.py,sha256=wo40MwtEjNTc73ZNTCmNC2-Img0zldUCaFGh9H3BZuE,14715
|
|
124
|
+
sqlspec/storage/backends/obstore.py,sha256=FnoVzTzzNn5NRXR8GgETqD3Rq9C5EWAmfWmY4JDFVJE,21214
|
|
125
|
+
sqlspec/utils/__init__.py,sha256=3nF4cd2RQX5SoCILETafwj-Vn6FVu7PCXtZhp6CbpL0,262
|
|
126
|
+
sqlspec/utils/cached_property.py,sha256=Sw_JZxfChSJu72gvYBJPF-89FyyIJAPf-1ETlDq-F2E,648
|
|
127
|
+
sqlspec/utils/correlation.py,sha256=4jqpjMivxI1tQ13Ed-P0hLdFHUKUQ9GlvIM69_HOlS4,4370
|
|
128
|
+
sqlspec/utils/deprecation.py,sha256=zrmb_eKRlLWVA6dWrjUbN3Vz6D3_-Z_15Ixk4H-sDRk,3850
|
|
129
|
+
sqlspec/utils/fixtures.py,sha256=q_Pghpmw2VgJ9P0TfkyjSF5PvdaD5Y2Laha0Bj4IDrA,1838
|
|
130
|
+
sqlspec/utils/logging.py,sha256=56a5tqx4jfTqm20WDyj5c7Dy-h_O0KambIKOMr1-Oms,3780
|
|
131
|
+
sqlspec/utils/module_loader.py,sha256=9LcmEhy4T0jgkCaDVkxX47PSgJOMeJ8IV67yXEWBp-U,3074
|
|
132
|
+
sqlspec/utils/serializers.py,sha256=TKsRryRcYMnb8Z8MGkYGClIxcYvC8CW7MsrPQTJqEcY,154
|
|
133
|
+
sqlspec/utils/singleton.py,sha256=KZ7481tlDAxq6gcAlpULVqPLNc9P0XkHOEp7hfWIHcI,1096
|
|
134
|
+
sqlspec/utils/statement_hashing.py,sha256=Y5OKJNucINCqXeRL9d2nGRzGuIlkK5RgK40QRZfedKU,6396
|
|
135
|
+
sqlspec/utils/sync_tools.py,sha256=ckP1_uLh40C2pDvdc4FsR4NkmZVa1zEB8jhUxPLIuAI,8726
|
|
136
|
+
sqlspec/utils/text.py,sha256=DpEnRuSDv3acp4VQQGEOQixlJnLGZsN5YBws4rkI6t0,4756
|
|
137
|
+
sqlspec/utils/type_guards.py,sha256=0sDlkB4HVl0uVA4asDNQgbGTu9Q7YaUrGllhneOi0LY,26755
|
|
138
|
+
sqlspec-0.14.0.dist-info/METADATA,sha256=5Ase9J2OW-vOrUWBzZ7ZvC1OFfzozztBckQZFTIdhyg,16663
|
|
139
|
+
sqlspec-0.14.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
140
|
+
sqlspec-0.14.0.dist-info/entry_points.txt,sha256=tdH4FLAT-q6lAu6G7ejwnHmsGTUfjW90j0CfiO_BXeU,48
|
|
141
|
+
sqlspec-0.14.0.dist-info/licenses/LICENSE,sha256=MdujfZ6l5HuLz4mElxlu049itenOR3gnhN1_Nd3nVcM,1078
|
|
142
|
+
sqlspec-0.14.0.dist-info/licenses/NOTICE,sha256=Lyir8ozXWov7CyYS4huVaOCNrtgL17P-bNV-5daLntQ,1634
|
|
143
|
+
sqlspec-0.14.0.dist-info/RECORD,,
|
sqlspec/service/__init__.py
DELETED
sqlspec/service/_util.py
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
from collections.abc import Sequence
|
|
2
|
-
from functools import partial
|
|
3
|
-
from typing import Any, Optional, TypeVar, Union, cast, overload
|
|
4
|
-
|
|
5
|
-
from sqlspec.driver.mixins._result_utils import _DEFAULT_TYPE_DECODERS, _default_msgspec_deserializer
|
|
6
|
-
from sqlspec.exceptions import SQLSpecError
|
|
7
|
-
from sqlspec.service.pagination import OffsetPagination
|
|
8
|
-
from sqlspec.statement.filters import FilterTypeT, LimitOffsetFilter, StatementFilter
|
|
9
|
-
from sqlspec.typing import BaseModel, DataclassProtocol, ModelDTOT, ModelT, Struct, convert, get_type_adapter
|
|
10
|
-
from sqlspec.utils.type_guards import is_dataclass, is_msgspec_struct, is_pydantic_model
|
|
11
|
-
|
|
12
|
-
__all__ = ("ResultConverter", "find_filter")
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
T = TypeVar("T")
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def find_filter(
|
|
19
|
-
filter_type: "type[FilterTypeT]", filters: "Optional[Sequence[StatementFilter]]" = None
|
|
20
|
-
) -> "Optional[FilterTypeT]":
|
|
21
|
-
"""Get the filter specified by filter type from the filters.
|
|
22
|
-
|
|
23
|
-
Args:
|
|
24
|
-
filter_type: The type of filter to find.
|
|
25
|
-
filters: filter types to apply to the query
|
|
26
|
-
|
|
27
|
-
Returns:
|
|
28
|
-
The match filter instance or None
|
|
29
|
-
"""
|
|
30
|
-
if filters is None:
|
|
31
|
-
return None
|
|
32
|
-
return next(
|
|
33
|
-
(cast("Optional[FilterTypeT]", filter_) for filter_ in filters if isinstance(filter_, filter_type)), None
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
# TODO: add overloads for each type of pagination in the future
|
|
38
|
-
class ResultConverter:
|
|
39
|
-
"""Simple mixin to help convert to dictionary or list of dictionaries to specified schema type.
|
|
40
|
-
|
|
41
|
-
Single objects are transformed to the supplied schema type, and lists of objects are transformed into a list of the supplied schema type.
|
|
42
|
-
|
|
43
|
-
Args:
|
|
44
|
-
data: A database model instance or row mapping.
|
|
45
|
-
Type: :class:`~sqlspec.typing.ModelDictT`
|
|
46
|
-
|
|
47
|
-
Returns:
|
|
48
|
-
The converted schema object.
|
|
49
|
-
"""
|
|
50
|
-
|
|
51
|
-
@overload
|
|
52
|
-
def to_schema(
|
|
53
|
-
self,
|
|
54
|
-
data: "ModelT",
|
|
55
|
-
total: "int | None" = None,
|
|
56
|
-
filters: "Sequence[StatementFilter] | None" = None,
|
|
57
|
-
*,
|
|
58
|
-
schema_type: None = None,
|
|
59
|
-
) -> "ModelT": ...
|
|
60
|
-
@overload
|
|
61
|
-
def to_schema(
|
|
62
|
-
self,
|
|
63
|
-
data: "dict[str, Any] | Struct | BaseModel | DataclassProtocol",
|
|
64
|
-
total: "int | None" = None,
|
|
65
|
-
filters: "Sequence[StatementFilter] | None" = None,
|
|
66
|
-
*,
|
|
67
|
-
schema_type: "type[ModelDTOT]",
|
|
68
|
-
) -> "ModelDTOT": ...
|
|
69
|
-
@overload
|
|
70
|
-
def to_schema(
|
|
71
|
-
self,
|
|
72
|
-
data: "Sequence[ModelT]",
|
|
73
|
-
total: "int | None" = None,
|
|
74
|
-
filters: "Sequence[StatementFilter] | None" = None,
|
|
75
|
-
*,
|
|
76
|
-
schema_type: None = None,
|
|
77
|
-
) -> "OffsetPagination[ModelT]": ...
|
|
78
|
-
@overload
|
|
79
|
-
def to_schema(
|
|
80
|
-
self,
|
|
81
|
-
data: "Sequence[dict[str, Any] | Struct | BaseModel | DataclassProtocol]",
|
|
82
|
-
total: "int | None" = None,
|
|
83
|
-
filters: "Sequence[StatementFilter] | None" = None,
|
|
84
|
-
*,
|
|
85
|
-
schema_type: "type[ModelDTOT]",
|
|
86
|
-
) -> "OffsetPagination[ModelDTOT]": ...
|
|
87
|
-
def to_schema(
|
|
88
|
-
self,
|
|
89
|
-
data: "ModelT | Sequence[ModelT] | dict[str, Any] | Struct | BaseModel | DataclassProtocol | Sequence[dict[str, Any] | Struct | BaseModel | DataclassProtocol]",
|
|
90
|
-
total: "int | None" = None,
|
|
91
|
-
filters: "Sequence[StatementFilter] | None" = None,
|
|
92
|
-
*,
|
|
93
|
-
schema_type: "type[ModelDTOT] | None" = None,
|
|
94
|
-
) -> "Union[ModelT, ModelDTOT , OffsetPagination[ModelT] , OffsetPagination[ModelDTOT]]":
|
|
95
|
-
if not isinstance(data, Sequence):
|
|
96
|
-
if schema_type is None:
|
|
97
|
-
return cast("ModelT", data)
|
|
98
|
-
if is_dataclass(schema_type):
|
|
99
|
-
return cast("ModelDTOT", schema_type(**data)) # type: ignore[operator]
|
|
100
|
-
if is_msgspec_struct(schema_type):
|
|
101
|
-
return cast(
|
|
102
|
-
"ModelDTOT",
|
|
103
|
-
convert(
|
|
104
|
-
obj=data,
|
|
105
|
-
type=schema_type,
|
|
106
|
-
from_attributes=True,
|
|
107
|
-
dec_hook=partial(_default_msgspec_deserializer, type_decoders=_DEFAULT_TYPE_DECODERS),
|
|
108
|
-
),
|
|
109
|
-
)
|
|
110
|
-
if is_pydantic_model(schema_type): # pyright: ignore
|
|
111
|
-
return cast(
|
|
112
|
-
"ModelDTOT",
|
|
113
|
-
get_type_adapter(schema_type).validate_python(data, from_attributes=True), # pyright: ignore
|
|
114
|
-
)
|
|
115
|
-
assert isinstance(data, Sequence)
|
|
116
|
-
limit_offset = find_filter(LimitOffsetFilter, filters=filters)
|
|
117
|
-
if schema_type is None:
|
|
118
|
-
return OffsetPagination[ModelT](
|
|
119
|
-
items=cast("list[ModelT]", data),
|
|
120
|
-
limit=limit_offset.limit if limit_offset else len(data),
|
|
121
|
-
offset=limit_offset.offset if limit_offset else 0,
|
|
122
|
-
total=total if total is not None else len(data),
|
|
123
|
-
)
|
|
124
|
-
converted_items: Sequence[ModelDTOT]
|
|
125
|
-
if is_dataclass(schema_type):
|
|
126
|
-
converted_items = [schema_type(**item) for item in data] # type: ignore[operator]
|
|
127
|
-
elif is_msgspec_struct(schema_type):
|
|
128
|
-
converted_items = convert(
|
|
129
|
-
obj=data,
|
|
130
|
-
type=list[schema_type], # type: ignore[valid-type]
|
|
131
|
-
from_attributes=True,
|
|
132
|
-
dec_hook=partial(_default_msgspec_deserializer, type_decoders=_DEFAULT_TYPE_DECODERS),
|
|
133
|
-
)
|
|
134
|
-
elif is_pydantic_model(schema_type): # pyright: ignore
|
|
135
|
-
converted_items = get_type_adapter(list[schema_type]).validate_python(data, from_attributes=True) # type: ignore[valid-type] # pyright: ignore[reportUnknownArgumentType]
|
|
136
|
-
else:
|
|
137
|
-
# This will also catch the case where a single item had an unrecognized schema_type
|
|
138
|
-
# if it somehow bypassed the initial single-item checks.
|
|
139
|
-
msg = "`schema_type` should be a valid Dataclass, Pydantic model or Msgspec struct"
|
|
140
|
-
raise SQLSpecError(msg)
|
|
141
|
-
|
|
142
|
-
return OffsetPagination[ModelDTOT](
|
|
143
|
-
items=cast("list[ModelDTOT]", converted_items),
|
|
144
|
-
limit=limit_offset.limit if limit_offset else len(data),
|
|
145
|
-
offset=limit_offset.offset if limit_offset else 0,
|
|
146
|
-
total=total if total is not None else len(data),
|
|
147
|
-
)
|
sqlspec/service/pagination.py
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
from collections.abc import Sequence
|
|
2
|
-
from dataclasses import dataclass
|
|
3
|
-
from typing import Generic, TypeVar
|
|
4
|
-
|
|
5
|
-
T = TypeVar("T")
|
|
6
|
-
|
|
7
|
-
__all__ = ("OffsetPagination",)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@dataclass
|
|
11
|
-
class OffsetPagination(Generic[T]):
|
|
12
|
-
"""Container for data returned using limit/offset pagination."""
|
|
13
|
-
|
|
14
|
-
__slots__ = ("items", "limit", "offset", "total")
|
|
15
|
-
|
|
16
|
-
items: Sequence[T]
|
|
17
|
-
"""List of data being sent as part of the response."""
|
|
18
|
-
limit: int
|
|
19
|
-
"""Maximal number of items to send."""
|
|
20
|
-
offset: int
|
|
21
|
-
"""Offset from the beginning of the query.
|
|
22
|
-
|
|
23
|
-
Identical to an index.
|
|
24
|
-
"""
|
|
25
|
-
total: int
|
|
26
|
-
"""Total number of items."""
|