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.

Files changed (110) hide show
  1. sqlspec/__init__.py +39 -1
  2. sqlspec/adapters/adbc/config.py +4 -40
  3. sqlspec/adapters/adbc/driver.py +29 -16
  4. sqlspec/adapters/aiosqlite/config.py +15 -20
  5. sqlspec/adapters/aiosqlite/driver.py +36 -18
  6. sqlspec/adapters/asyncmy/config.py +16 -33
  7. sqlspec/adapters/asyncmy/driver.py +23 -16
  8. sqlspec/adapters/asyncpg/config.py +19 -61
  9. sqlspec/adapters/asyncpg/driver.py +41 -18
  10. sqlspec/adapters/bigquery/config.py +2 -43
  11. sqlspec/adapters/bigquery/driver.py +26 -14
  12. sqlspec/adapters/duckdb/config.py +2 -49
  13. sqlspec/adapters/duckdb/driver.py +35 -16
  14. sqlspec/adapters/oracledb/config.py +30 -83
  15. sqlspec/adapters/oracledb/driver.py +54 -27
  16. sqlspec/adapters/psqlpy/config.py +17 -57
  17. sqlspec/adapters/psqlpy/driver.py +28 -8
  18. sqlspec/adapters/psycopg/config.py +30 -73
  19. sqlspec/adapters/psycopg/driver.py +69 -24
  20. sqlspec/adapters/sqlite/config.py +3 -21
  21. sqlspec/adapters/sqlite/driver.py +50 -26
  22. sqlspec/cli.py +248 -0
  23. sqlspec/config.py +18 -20
  24. sqlspec/driver/_async.py +28 -10
  25. sqlspec/driver/_common.py +5 -4
  26. sqlspec/driver/_sync.py +28 -10
  27. sqlspec/driver/mixins/__init__.py +6 -0
  28. sqlspec/driver/mixins/_cache.py +114 -0
  29. sqlspec/driver/mixins/_pipeline.py +0 -4
  30. sqlspec/{service/base.py → driver/mixins/_query_tools.py} +86 -421
  31. sqlspec/driver/mixins/_result_utils.py +0 -2
  32. sqlspec/driver/mixins/_sql_translator.py +0 -2
  33. sqlspec/driver/mixins/_storage.py +4 -18
  34. sqlspec/driver/mixins/_type_coercion.py +0 -2
  35. sqlspec/driver/parameters.py +4 -4
  36. sqlspec/extensions/aiosql/adapter.py +4 -4
  37. sqlspec/extensions/litestar/__init__.py +2 -1
  38. sqlspec/extensions/litestar/cli.py +48 -0
  39. sqlspec/extensions/litestar/plugin.py +3 -0
  40. sqlspec/loader.py +1 -1
  41. sqlspec/migrations/__init__.py +23 -0
  42. sqlspec/migrations/base.py +390 -0
  43. sqlspec/migrations/commands.py +525 -0
  44. sqlspec/migrations/runner.py +215 -0
  45. sqlspec/migrations/tracker.py +153 -0
  46. sqlspec/migrations/utils.py +89 -0
  47. sqlspec/protocols.py +37 -3
  48. sqlspec/statement/builder/__init__.py +8 -8
  49. sqlspec/statement/builder/{column.py → _column.py} +82 -52
  50. sqlspec/statement/builder/{ddl.py → _ddl.py} +5 -5
  51. sqlspec/statement/builder/_ddl_utils.py +1 -1
  52. sqlspec/statement/builder/{delete.py → _delete.py} +1 -1
  53. sqlspec/statement/builder/{insert.py → _insert.py} +1 -1
  54. sqlspec/statement/builder/{merge.py → _merge.py} +1 -1
  55. sqlspec/statement/builder/_parsing_utils.py +5 -3
  56. sqlspec/statement/builder/{select.py → _select.py} +59 -61
  57. sqlspec/statement/builder/{update.py → _update.py} +2 -2
  58. sqlspec/statement/builder/mixins/__init__.py +24 -30
  59. sqlspec/statement/builder/mixins/{_set_ops.py → _cte_and_set_ops.py} +86 -2
  60. sqlspec/statement/builder/mixins/{_delete_from.py → _delete_operations.py} +2 -0
  61. sqlspec/statement/builder/mixins/{_insert_values.py → _insert_operations.py} +70 -1
  62. sqlspec/statement/builder/mixins/{_merge_clauses.py → _merge_operations.py} +2 -0
  63. sqlspec/statement/builder/mixins/_order_limit_operations.py +123 -0
  64. sqlspec/statement/builder/mixins/{_pivot.py → _pivot_operations.py} +71 -2
  65. sqlspec/statement/builder/mixins/_select_operations.py +612 -0
  66. sqlspec/statement/builder/mixins/{_update_set.py → _update_operations.py} +73 -2
  67. sqlspec/statement/builder/mixins/_where_clause.py +536 -0
  68. sqlspec/statement/cache.py +50 -0
  69. sqlspec/statement/filters.py +37 -8
  70. sqlspec/statement/parameters.py +154 -25
  71. sqlspec/statement/pipelines/__init__.py +1 -1
  72. sqlspec/statement/pipelines/context.py +4 -4
  73. sqlspec/statement/pipelines/transformers/_expression_simplifier.py +3 -3
  74. sqlspec/statement/pipelines/validators/_parameter_style.py +22 -22
  75. sqlspec/statement/pipelines/validators/_performance.py +1 -5
  76. sqlspec/statement/sql.py +246 -176
  77. sqlspec/utils/__init__.py +2 -1
  78. sqlspec/utils/statement_hashing.py +203 -0
  79. sqlspec/utils/type_guards.py +32 -0
  80. {sqlspec-0.13.0.dist-info → sqlspec-0.14.0.dist-info}/METADATA +1 -1
  81. sqlspec-0.14.0.dist-info/RECORD +143 -0
  82. sqlspec-0.14.0.dist-info/entry_points.txt +2 -0
  83. sqlspec/service/__init__.py +0 -4
  84. sqlspec/service/_util.py +0 -147
  85. sqlspec/service/pagination.py +0 -26
  86. sqlspec/statement/builder/mixins/_aggregate_functions.py +0 -250
  87. sqlspec/statement/builder/mixins/_case_builder.py +0 -91
  88. sqlspec/statement/builder/mixins/_common_table_expr.py +0 -90
  89. sqlspec/statement/builder/mixins/_from.py +0 -63
  90. sqlspec/statement/builder/mixins/_group_by.py +0 -118
  91. sqlspec/statement/builder/mixins/_having.py +0 -35
  92. sqlspec/statement/builder/mixins/_insert_from_select.py +0 -47
  93. sqlspec/statement/builder/mixins/_insert_into.py +0 -36
  94. sqlspec/statement/builder/mixins/_limit_offset.py +0 -53
  95. sqlspec/statement/builder/mixins/_order_by.py +0 -46
  96. sqlspec/statement/builder/mixins/_returning.py +0 -37
  97. sqlspec/statement/builder/mixins/_select_columns.py +0 -61
  98. sqlspec/statement/builder/mixins/_unpivot.py +0 -77
  99. sqlspec/statement/builder/mixins/_update_from.py +0 -55
  100. sqlspec/statement/builder/mixins/_update_table.py +0 -29
  101. sqlspec/statement/builder/mixins/_where.py +0 -401
  102. sqlspec/statement/builder/mixins/_window_functions.py +0 -86
  103. sqlspec/statement/parameter_manager.py +0 -220
  104. sqlspec/statement/sql_compiler.py +0 -140
  105. sqlspec-0.13.0.dist-info/RECORD +0 -150
  106. /sqlspec/statement/builder/{base.py → _base.py} +0 -0
  107. /sqlspec/statement/builder/mixins/{_join.py → _join_operations.py} +0 -0
  108. {sqlspec-0.13.0.dist-info → sqlspec-0.14.0.dist-info}/WHEEL +0 -0
  109. {sqlspec-0.13.0.dist-info → sqlspec-0.14.0.dist-info}/licenses/LICENSE +0 -0
  110. {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))}"
@@ -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)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sqlspec
3
- Version: 0.13.0
3
+ Version: 0.14.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/
@@ -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,,
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ sqlspec = sqlspec.cli:run_cli
@@ -1,4 +0,0 @@
1
- from sqlspec.service.base import SQLSpecAsyncService, SQLSpecSyncService
2
- from sqlspec.service.pagination import OffsetPagination
3
-
4
- __all__ = ("OffsetPagination", "SQLSpecAsyncService", "SQLSpecSyncService")
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
- )
@@ -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."""