ormlambda 3.11.2__py3-none-any.whl → 3.34.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.
- ormlambda/__init__.py +3 -1
- ormlambda/caster/__init__.py +1 -1
- ormlambda/caster/caster.py +29 -12
- ormlambda/common/abstract_classes/clause_info_converter.py +65 -0
- ormlambda/common/abstract_classes/decomposition_query.py +27 -68
- ormlambda/common/abstract_classes/non_query_base.py +10 -8
- ormlambda/common/abstract_classes/query_base.py +3 -1
- ormlambda/common/errors/__init__.py +29 -0
- ormlambda/common/interfaces/ICustomAlias.py +1 -1
- ormlambda/common/interfaces/IQueryCommand.py +6 -2
- ormlambda/dialects/__init__.py +39 -0
- ormlambda/dialects/default/__init__.py +1 -0
- ormlambda/dialects/default/base.py +39 -0
- ormlambda/dialects/interface/__init__.py +1 -0
- ormlambda/dialects/interface/dialect.py +78 -0
- ormlambda/dialects/mysql/__init__.py +38 -0
- ormlambda/dialects/mysql/base.py +388 -0
- ormlambda/dialects/mysql/caster/caster.py +39 -0
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/__init__.py +1 -0
- ormlambda/dialects/mysql/caster/types/boolean.py +35 -0
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/bytes.py +7 -7
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/datetime.py +7 -7
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/float.py +7 -7
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/int.py +7 -7
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/iterable.py +7 -7
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/none.py +8 -7
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/point.py +4 -4
- ormlambda/{databases/my_sql → dialects/mysql}/caster/types/string.py +7 -7
- ormlambda/{databases/my_sql → dialects/mysql}/clauses/ST_AsText.py +8 -7
- ormlambda/{databases/my_sql → dialects/mysql}/clauses/ST_Contains.py +10 -5
- ormlambda/dialects/mysql/clauses/__init__.py +13 -0
- ormlambda/dialects/mysql/clauses/count.py +33 -0
- ormlambda/dialects/mysql/clauses/delete.py +9 -0
- ormlambda/dialects/mysql/clauses/group_by.py +17 -0
- ormlambda/dialects/mysql/clauses/having.py +12 -0
- ormlambda/dialects/mysql/clauses/insert.py +9 -0
- ormlambda/dialects/mysql/clauses/joins.py +14 -0
- ormlambda/dialects/mysql/clauses/limit.py +6 -0
- ormlambda/dialects/mysql/clauses/offset.py +6 -0
- ormlambda/dialects/mysql/clauses/order.py +8 -0
- ormlambda/dialects/mysql/clauses/update.py +8 -0
- ormlambda/dialects/mysql/clauses/upsert.py +9 -0
- ormlambda/dialects/mysql/clauses/where.py +7 -0
- ormlambda/dialects/mysql/mysqlconnector.py +46 -0
- ormlambda/dialects/mysql/repository/__init__.py +1 -0
- ormlambda/dialects/mysql/repository/repository.py +212 -0
- ormlambda/dialects/mysql/types.py +732 -0
- ormlambda/dialects/sqlite/__init__.py +5 -0
- ormlambda/dialects/sqlite/base.py +47 -0
- ormlambda/dialects/sqlite/pysqlite.py +32 -0
- ormlambda/engine/__init__.py +1 -0
- ormlambda/engine/base.py +77 -0
- ormlambda/engine/create.py +9 -23
- ormlambda/engine/url.py +34 -19
- ormlambda/env.py +30 -0
- ormlambda/errors.py +17 -0
- ormlambda/model/base_model.py +7 -9
- ormlambda/repository/base_repository.py +36 -5
- ormlambda/repository/interfaces/IRepositoryBase.py +119 -12
- ormlambda/repository/response.py +134 -0
- ormlambda/sql/clause_info/__init__.py +2 -1
- ormlambda/sql/clause_info/aggregate_function_base.py +96 -0
- ormlambda/sql/clause_info/clause_info.py +35 -115
- ormlambda/sql/clause_info/interface/IClauseInfo.py +37 -0
- ormlambda/sql/clause_info/interface/__init__.py +1 -0
- ormlambda/sql/clauses/__init__.py +14 -0
- ormlambda/{databases/my_sql → sql}/clauses/alias.py +23 -6
- ormlambda/{databases/my_sql → sql}/clauses/count.py +15 -1
- ormlambda/{databases/my_sql → sql}/clauses/delete.py +22 -7
- ormlambda/sql/clauses/group_by.py +30 -0
- ormlambda/{databases/my_sql → sql}/clauses/having.py +7 -2
- ormlambda/{databases/my_sql → sql}/clauses/insert.py +16 -9
- ormlambda/sql/clauses/interfaces/__init__.py +5 -0
- ormlambda/sql/clauses/join/__init__.py +1 -0
- ormlambda/{databases/my_sql → sql/clauses/join}/join_context.py +15 -7
- ormlambda/{databases/my_sql → sql}/clauses/joins.py +29 -19
- ormlambda/sql/clauses/limit.py +15 -0
- ormlambda/sql/clauses/offset.py +15 -0
- ormlambda/{databases/my_sql → sql}/clauses/order.py +14 -24
- ormlambda/{databases/my_sql → sql}/clauses/select.py +14 -13
- ormlambda/{databases/my_sql → sql}/clauses/update.py +24 -11
- ormlambda/{databases/my_sql → sql}/clauses/upsert.py +19 -10
- ormlambda/{databases/my_sql → sql}/clauses/where.py +28 -8
- ormlambda/sql/column/__init__.py +1 -0
- ormlambda/sql/{column.py → column/column.py} +85 -22
- ormlambda/sql/comparer.py +51 -37
- ormlambda/sql/compiler.py +668 -0
- ormlambda/sql/ddl.py +82 -0
- ormlambda/sql/elements.py +36 -0
- ormlambda/sql/foreign_key.py +61 -39
- ormlambda/{databases/my_sql → sql}/functions/concat.py +13 -5
- ormlambda/{databases/my_sql → sql}/functions/max.py +9 -4
- ormlambda/{databases/my_sql → sql}/functions/min.py +9 -13
- ormlambda/{databases/my_sql → sql}/functions/sum.py +8 -10
- ormlambda/sql/sqltypes.py +647 -0
- ormlambda/sql/table/__init__.py +1 -1
- ormlambda/sql/table/table.py +175 -0
- ormlambda/sql/table/table_constructor.py +1 -208
- ormlambda/sql/type_api.py +35 -0
- ormlambda/sql/types.py +3 -1
- ormlambda/sql/visitors.py +74 -0
- ormlambda/statements/__init__.py +1 -0
- ormlambda/statements/base_statement.py +34 -40
- ormlambda/statements/interfaces/IStatements.py +28 -21
- ormlambda/statements/query_builder.py +163 -0
- ormlambda/{databases/my_sql → statements}/statements.py +68 -210
- ormlambda/statements/types.py +2 -2
- ormlambda/types/__init__.py +24 -0
- ormlambda/types/metadata.py +42 -0
- ormlambda/util/__init__.py +87 -0
- ormlambda/{utils → util}/module_tree/dynamic_module.py +4 -3
- ormlambda/util/plugin_loader.py +32 -0
- ormlambda/util/typing.py +6 -0
- ormlambda-3.34.0.dist-info/AUTHORS +32 -0
- {ormlambda-3.11.2.dist-info → ormlambda-3.34.0.dist-info}/METADATA +56 -10
- ormlambda-3.34.0.dist-info/RECORD +152 -0
- ormlambda/components/__init__.py +0 -4
- ormlambda/components/delete/__init__.py +0 -2
- ormlambda/components/delete/abstract_delete.py +0 -17
- ormlambda/components/insert/__init__.py +0 -2
- ormlambda/components/insert/abstract_insert.py +0 -25
- ormlambda/components/select/__init__.py +0 -1
- ormlambda/components/update/__init__.py +0 -2
- ormlambda/components/update/abstract_update.py +0 -29
- ormlambda/components/upsert/__init__.py +0 -2
- ormlambda/components/upsert/abstract_upsert.py +0 -25
- ormlambda/databases/__init__.py +0 -5
- ormlambda/databases/my_sql/__init__.py +0 -4
- ormlambda/databases/my_sql/caster/caster.py +0 -39
- ormlambda/databases/my_sql/clauses/__init__.py +0 -20
- ormlambda/databases/my_sql/clauses/create_database.py +0 -35
- ormlambda/databases/my_sql/clauses/drop_database.py +0 -17
- ormlambda/databases/my_sql/clauses/drop_table.py +0 -23
- ormlambda/databases/my_sql/clauses/group_by.py +0 -31
- ormlambda/databases/my_sql/clauses/limit.py +0 -17
- ormlambda/databases/my_sql/clauses/offset.py +0 -17
- ormlambda/databases/my_sql/repository/__init__.py +0 -1
- ormlambda/databases/my_sql/repository/repository.py +0 -351
- ormlambda/engine/template.py +0 -47
- ormlambda/sql/dtypes.py +0 -94
- ormlambda/utils/__init__.py +0 -1
- ormlambda-3.11.2.dist-info/RECORD +0 -120
- /ormlambda/{databases/my_sql → dialects/mysql}/caster/__init__.py +0 -0
- /ormlambda/{databases/my_sql/types.py → dialects/mysql/repository/pool_types.py} +0 -0
- /ormlambda/{components/delete → sql/clauses/interfaces}/IDelete.py +0 -0
- /ormlambda/{components/insert → sql/clauses/interfaces}/IInsert.py +0 -0
- /ormlambda/{components/select → sql/clauses/interfaces}/ISelect.py +0 -0
- /ormlambda/{components/update → sql/clauses/interfaces}/IUpdate.py +0 -0
- /ormlambda/{components/upsert → sql/clauses/interfaces}/IUpsert.py +0 -0
- /ormlambda/{databases/my_sql → sql}/functions/__init__.py +0 -0
- /ormlambda/{utils → util}/module_tree/__init__.py +0 -0
- /ormlambda/{utils → util}/module_tree/dfs_traversal.py +0 -0
- {ormlambda-3.11.2.dist-info → ormlambda-3.34.0.dist-info}/LICENSE +0 -0
- {ormlambda-3.11.2.dist-info → ormlambda-3.34.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,647 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
import decimal
|
3
|
+
import datetime as dt
|
4
|
+
import enum
|
5
|
+
import inspect
|
6
|
+
from types import NoneType
|
7
|
+
from typing import Literal, Optional, Any, Type, cast, get_args, overload
|
8
|
+
from .type_api import TypeEngine
|
9
|
+
import ormlambda.util as util
|
10
|
+
from uuid import UUID as _python_UUID
|
11
|
+
from shapely import Point as _python_Point
|
12
|
+
|
13
|
+
class _NoArg(enum.Enum):
|
14
|
+
NO_ARG = 0
|
15
|
+
|
16
|
+
def __repr__(self):
|
17
|
+
return f"_NoArg.{self.name}"
|
18
|
+
|
19
|
+
|
20
|
+
NO_ARG = _NoArg.NO_ARG
|
21
|
+
|
22
|
+
|
23
|
+
# region Numeric Types
|
24
|
+
class Integer(TypeEngine[int]):
|
25
|
+
"""Standard integer type."""
|
26
|
+
|
27
|
+
__visit_name__ = "integer"
|
28
|
+
|
29
|
+
@property
|
30
|
+
def python_type(self) -> Type[int]:
|
31
|
+
return int
|
32
|
+
|
33
|
+
def _resolve_for_literal_value(self, value: int) -> TypeEngine[int]:
|
34
|
+
if value.bit_length() >= 32:
|
35
|
+
return _BIGINTEGER
|
36
|
+
return self
|
37
|
+
|
38
|
+
|
39
|
+
class SmallInteger(Integer):
|
40
|
+
"""Small-range integer."""
|
41
|
+
|
42
|
+
__visit_name__ = "small_integer"
|
43
|
+
|
44
|
+
|
45
|
+
class BigInteger(Integer):
|
46
|
+
"""Large-range integer."""
|
47
|
+
|
48
|
+
__visit_name__ = "big_integer"
|
49
|
+
|
50
|
+
|
51
|
+
type NumericType = float | decimal.Decimal
|
52
|
+
|
53
|
+
|
54
|
+
class NumericCommon[T: NumericType](TypeEngine[T]):
|
55
|
+
"""Exact numeric type with precision and scale."""
|
56
|
+
|
57
|
+
def __init__(
|
58
|
+
self,
|
59
|
+
*,
|
60
|
+
precision: Optional[int],
|
61
|
+
scale: Optional[int],
|
62
|
+
asdecimal: bool,
|
63
|
+
):
|
64
|
+
self.precision = precision
|
65
|
+
self.scale = scale
|
66
|
+
self.asdecimal = asdecimal
|
67
|
+
|
68
|
+
@property
|
69
|
+
def python_type(self) -> Type[T]:
|
70
|
+
if self.asdecimal:
|
71
|
+
return decimal.Decimal
|
72
|
+
return float
|
73
|
+
|
74
|
+
|
75
|
+
class Numeric[T: NumericType](NumericCommon[T]):
|
76
|
+
__visit_name__ = "numeric"
|
77
|
+
|
78
|
+
@overload
|
79
|
+
def __init__(
|
80
|
+
self: Numeric[float],
|
81
|
+
precision: Optional[int] = ...,
|
82
|
+
scale: Optional[int] = ...,
|
83
|
+
asdecimal: Literal[False] = ...,
|
84
|
+
): ...
|
85
|
+
@overload
|
86
|
+
def __init__(
|
87
|
+
self: Numeric[decimal.Decimal],
|
88
|
+
precision: Optional[int] = ...,
|
89
|
+
scale: Optional[int] = ...,
|
90
|
+
asdecimal: Literal[True] = ...,
|
91
|
+
): ...
|
92
|
+
def __init__(
|
93
|
+
self,
|
94
|
+
*,
|
95
|
+
precision: Optional[int] = None,
|
96
|
+
scale: Optional[int] = None,
|
97
|
+
asdecimal: bool = True,
|
98
|
+
):
|
99
|
+
super().__init__(
|
100
|
+
precision=precision,
|
101
|
+
scale=scale,
|
102
|
+
asdecimal=asdecimal,
|
103
|
+
)
|
104
|
+
|
105
|
+
|
106
|
+
class Float[T: NumericType](NumericCommon[T]):
|
107
|
+
"""Floating point type."""
|
108
|
+
|
109
|
+
__visit_name__ = "float"
|
110
|
+
|
111
|
+
@overload
|
112
|
+
def __init__(
|
113
|
+
self: Numeric[float],
|
114
|
+
precision: Optional[int] = ...,
|
115
|
+
asdecimal: Literal[False] = ...,
|
116
|
+
): ...
|
117
|
+
@overload
|
118
|
+
def __init__(
|
119
|
+
self: Numeric[decimal.Decimal],
|
120
|
+
precision: Optional[int] = ...,
|
121
|
+
asdecimal: Literal[True] = ...,
|
122
|
+
): ...
|
123
|
+
def __init__(
|
124
|
+
self,
|
125
|
+
*,
|
126
|
+
precision: Optional[int] = None,
|
127
|
+
asdecimal: bool = False,
|
128
|
+
):
|
129
|
+
super().__init__(
|
130
|
+
precision=precision,
|
131
|
+
scale=None,
|
132
|
+
asdecimal=asdecimal,
|
133
|
+
)
|
134
|
+
|
135
|
+
|
136
|
+
class Real[T: NumericType](Numeric[T]):
|
137
|
+
"""Real number type."""
|
138
|
+
|
139
|
+
__visit_name__ = "real"
|
140
|
+
|
141
|
+
|
142
|
+
class Double[T: NumericType](Float[T]):
|
143
|
+
"""Double precision floating point."""
|
144
|
+
|
145
|
+
__visit_name__ = "double"
|
146
|
+
|
147
|
+
|
148
|
+
# endregion
|
149
|
+
|
150
|
+
|
151
|
+
# region String Types
|
152
|
+
class String(TypeEngine[str]):
|
153
|
+
"""The base for all string and character types.
|
154
|
+
|
155
|
+
In SQL, corresponds to VARCHAR.
|
156
|
+
"""
|
157
|
+
|
158
|
+
__visit_name__ = "string"
|
159
|
+
|
160
|
+
def __init__(
|
161
|
+
self,
|
162
|
+
length: Optional[int] = None,
|
163
|
+
collation: Optional[str] = None,
|
164
|
+
):
|
165
|
+
self.length = length
|
166
|
+
self.collation = collation
|
167
|
+
|
168
|
+
@property
|
169
|
+
def python_type(self) -> Type[str]:
|
170
|
+
return str
|
171
|
+
|
172
|
+
def _resolve_for_literal_value(self, value: str) -> TypeEngine[str]:
|
173
|
+
if value.isascii():
|
174
|
+
return _STRING
|
175
|
+
return _UNICODE
|
176
|
+
|
177
|
+
|
178
|
+
class Text(String):
|
179
|
+
"""Unbounded length text type."""
|
180
|
+
|
181
|
+
__visit_name__ = "text"
|
182
|
+
|
183
|
+
def __init__(
|
184
|
+
self,
|
185
|
+
length: Optional[int] = None,
|
186
|
+
collation: Optional[str] = None,
|
187
|
+
):
|
188
|
+
super().__init__(length, collation)
|
189
|
+
|
190
|
+
|
191
|
+
class Unicode(String):
|
192
|
+
"""Variable length Unicode string."""
|
193
|
+
|
194
|
+
__visit_name__ = "unicode"
|
195
|
+
|
196
|
+
def __init__(
|
197
|
+
self,
|
198
|
+
length: Optional[int] = None,
|
199
|
+
collation: Optional[str] = None,
|
200
|
+
):
|
201
|
+
super().__init__(length, collation)
|
202
|
+
|
203
|
+
|
204
|
+
class UnicodeText(String):
|
205
|
+
"""Unbounded length Unicode text."""
|
206
|
+
|
207
|
+
__visit_name__ = "unicode_text"
|
208
|
+
|
209
|
+
def __init__(
|
210
|
+
self,
|
211
|
+
length: Optional[int] = None,
|
212
|
+
collation: Optional[str] = None,
|
213
|
+
):
|
214
|
+
super().__init__(length, collation)
|
215
|
+
|
216
|
+
|
217
|
+
# endregion
|
218
|
+
|
219
|
+
|
220
|
+
# region Date and Time Types
|
221
|
+
class Date(TypeEngine[dt.date]):
|
222
|
+
"""Date type."""
|
223
|
+
|
224
|
+
__visit_name__ = "date"
|
225
|
+
|
226
|
+
@property
|
227
|
+
def python_type(self) -> Type[dt.date]:
|
228
|
+
return dt.date
|
229
|
+
|
230
|
+
|
231
|
+
class Time(TypeEngine[dt.time]):
|
232
|
+
"""Time type."""
|
233
|
+
|
234
|
+
__visit_name__ = "time"
|
235
|
+
|
236
|
+
def __init__(
|
237
|
+
self,
|
238
|
+
timezone: bool = False,
|
239
|
+
):
|
240
|
+
self.timezone = timezone
|
241
|
+
|
242
|
+
@property
|
243
|
+
def python_type(self) -> Type[dt.time]:
|
244
|
+
return dt.time
|
245
|
+
|
246
|
+
def _resolve_for_literal_value(self, value: dt.datetime) -> TypeEngine[dt.datetime]:
|
247
|
+
has_timezone = value.tzinfo is not None
|
248
|
+
if has_timezone and not self.timezone:
|
249
|
+
return TIME_TIMEZONE
|
250
|
+
return self
|
251
|
+
|
252
|
+
|
253
|
+
class Datetime(TypeEngine[dt.datetime]):
|
254
|
+
"""Date and time type."""
|
255
|
+
|
256
|
+
__visit_name__ = "datetime"
|
257
|
+
|
258
|
+
def __init__(
|
259
|
+
self,
|
260
|
+
timezone: bool = False,
|
261
|
+
):
|
262
|
+
self.timezone = timezone
|
263
|
+
|
264
|
+
@property
|
265
|
+
def python_type(self) -> Type[dt.datetime]:
|
266
|
+
return dt.datetime
|
267
|
+
|
268
|
+
def _resolve_for_literal_value(self, value: dt.datetime) -> TypeEngine[dt.datetime]:
|
269
|
+
has_timezone = value.tzinfo is not None
|
270
|
+
if has_timezone and not self.timezone:
|
271
|
+
return DATETIME_TIMEZONE
|
272
|
+
return self
|
273
|
+
|
274
|
+
|
275
|
+
class Timestamp(TypeEngine[int]):
|
276
|
+
"""Timestamp type with optional timezone support."""
|
277
|
+
|
278
|
+
__visit_name__ = "timestamp"
|
279
|
+
|
280
|
+
def __init__(
|
281
|
+
self,
|
282
|
+
timezone: bool = False,
|
283
|
+
precision: Optional[int] = None,
|
284
|
+
):
|
285
|
+
self.timezone = timezone
|
286
|
+
self.precision = precision
|
287
|
+
|
288
|
+
@property
|
289
|
+
def python_type(self) -> Type[int]:
|
290
|
+
return int
|
291
|
+
|
292
|
+
|
293
|
+
# endregion
|
294
|
+
|
295
|
+
|
296
|
+
# region Boolean Type
|
297
|
+
class Boolean(TypeEngine[bool]):
|
298
|
+
"""Boolean type."""
|
299
|
+
|
300
|
+
__visit_name__ = "boolean"
|
301
|
+
|
302
|
+
@property
|
303
|
+
def python_type(self) -> Type[bool]:
|
304
|
+
return bool
|
305
|
+
|
306
|
+
|
307
|
+
# endregion
|
308
|
+
|
309
|
+
|
310
|
+
# region Binary Types
|
311
|
+
|
312
|
+
|
313
|
+
class _Binary(TypeEngine[bytes]):
|
314
|
+
"""Define base behavior for binary types."""
|
315
|
+
|
316
|
+
def __init__(self, length: Optional[int] = None):
|
317
|
+
self.length = length
|
318
|
+
|
319
|
+
|
320
|
+
class LargeBinary(_Binary):
|
321
|
+
"""Binary data type."""
|
322
|
+
|
323
|
+
__visit_name__ = "large_binary"
|
324
|
+
|
325
|
+
@property
|
326
|
+
def python_type(self) -> Type[bytes]:
|
327
|
+
return bytes
|
328
|
+
|
329
|
+
|
330
|
+
class Varbinary(_Binary):
|
331
|
+
"""Variable-length binary data."""
|
332
|
+
|
333
|
+
__visit_name__ = "varbinary"
|
334
|
+
|
335
|
+
def __init__(
|
336
|
+
self,
|
337
|
+
length: Optional[int] = None,
|
338
|
+
):
|
339
|
+
self.length = length
|
340
|
+
|
341
|
+
|
342
|
+
# endregion
|
343
|
+
|
344
|
+
|
345
|
+
# region Other Types
|
346
|
+
type EnumType = str | enum.Enum
|
347
|
+
|
348
|
+
|
349
|
+
class Enum(String, TypeEngine[EnumType]):
|
350
|
+
"""Enumerated type."""
|
351
|
+
|
352
|
+
__visit_name__ = "enum"
|
353
|
+
|
354
|
+
def __init__(
|
355
|
+
self,
|
356
|
+
*enums: str,
|
357
|
+
name: Optional[str] = None,
|
358
|
+
schema: Optional[str] = None,
|
359
|
+
):
|
360
|
+
self.enums = enums
|
361
|
+
self.name = name
|
362
|
+
self.schema = schema
|
363
|
+
|
364
|
+
@property
|
365
|
+
def python_type(self) -> Type[EnumType]:
|
366
|
+
if not self.enums:
|
367
|
+
return super().python_type
|
368
|
+
return enum.Enum
|
369
|
+
|
370
|
+
def _resolve_for_literal_value(self, value: dt.datetime) -> TypeEngine[dt.datetime]:
|
371
|
+
tv = type(value)
|
372
|
+
type_ = self._resolve_for_literal_value(tv, tv, tv)
|
373
|
+
assert type_ is not None
|
374
|
+
return type_
|
375
|
+
|
376
|
+
def _resolve_for_python_type(
|
377
|
+
self,
|
378
|
+
python_type: Type[Any],
|
379
|
+
matched_on: Any,
|
380
|
+
matched_on_flattened: Type[Any],
|
381
|
+
) -> Optional[Enum]:
|
382
|
+
# "generic form" indicates we were placed in a type map
|
383
|
+
# as ``sqlalchemy.Enum(enum.Enum)`` which indicates we need to
|
384
|
+
# get enumerated values from the datatype
|
385
|
+
we_are_generic_form = self._enums_argument == [enum.Enum]
|
386
|
+
|
387
|
+
native_enum = None
|
388
|
+
|
389
|
+
def process_literal(pt):
|
390
|
+
# for a literal, where we need to get its contents, parse it out.
|
391
|
+
enum_args = get_args(pt)
|
392
|
+
bad_args = [arg for arg in enum_args if not isinstance(arg, str)]
|
393
|
+
if bad_args:
|
394
|
+
raise ValueError(f"Can't create string-based Enum datatype from non-string " f"values: {', '.join(repr(x) for x in bad_args)}. Please " f"provide an explicit Enum datatype for this Python type")
|
395
|
+
native_enum = False
|
396
|
+
return enum_args, native_enum
|
397
|
+
|
398
|
+
if not we_are_generic_form and python_type is matched_on:
|
399
|
+
# if we have enumerated values, and the incoming python
|
400
|
+
# type is exactly the one that matched in the type map,
|
401
|
+
# then we use these enumerated values and dont try to parse
|
402
|
+
# what's incoming
|
403
|
+
enum_args = self._enums_argument
|
404
|
+
|
405
|
+
elif util.is_literal(python_type):
|
406
|
+
enum_args, native_enum = process_literal(python_type)
|
407
|
+
elif util.is_pep695(python_type):
|
408
|
+
value = python_type.__value__
|
409
|
+
if not util.is_literal(value):
|
410
|
+
raise ValueError(f"Can't associate TypeAliasType '{python_type}' to an " "Enum since it's not a direct alias of a Literal. Only " "aliases in this form `type my_alias = Literal['a', " "'b']` are supported when generating Enums.")
|
411
|
+
enum_args, native_enum = process_literal(value)
|
412
|
+
|
413
|
+
elif isinstance(python_type, type) and issubclass(python_type, enum.Enum):
|
414
|
+
# same for an enum.Enum
|
415
|
+
enum_args = [python_type]
|
416
|
+
|
417
|
+
else:
|
418
|
+
enum_args = self._enums_argument
|
419
|
+
|
420
|
+
# make a new Enum that looks like this one.
|
421
|
+
# arguments or other rules
|
422
|
+
kw = self._make_enum_kw({})
|
423
|
+
|
424
|
+
if native_enum is False:
|
425
|
+
kw["native_enum"] = False
|
426
|
+
|
427
|
+
kw["length"] = NO_ARG if self.length == 0 else self.length
|
428
|
+
return cast(
|
429
|
+
Enum,
|
430
|
+
self._generic_type_affinity(_enums=enum_args, **kw), # type: ignore # noqa: E501
|
431
|
+
)
|
432
|
+
|
433
|
+
def _setup_for_values(self, values, objects, kw):
|
434
|
+
self.enums = list(values)
|
435
|
+
|
436
|
+
self._valid_lookup = dict(zip(reversed(objects), reversed(values)))
|
437
|
+
|
438
|
+
self._object_lookup = dict(zip(values, objects))
|
439
|
+
|
440
|
+
self._valid_lookup.update([(value, self._valid_lookup[self._object_lookup[value]]) for value in values])
|
441
|
+
|
442
|
+
class Point(TypeEngine[_python_Point]):
|
443
|
+
__visit_name__ = 'point'
|
444
|
+
|
445
|
+
@property
|
446
|
+
def python_type(self)->Type[_python_Point]:
|
447
|
+
return _python_Point
|
448
|
+
|
449
|
+
class JSON(TypeEngine[Any]):
|
450
|
+
"""JSON data type."""
|
451
|
+
|
452
|
+
__visit_name__ = "json"
|
453
|
+
|
454
|
+
|
455
|
+
type UuidType = str | _python_UUID
|
456
|
+
|
457
|
+
|
458
|
+
class UUID[T: UuidType](TypeEngine[UuidType]):
|
459
|
+
"""UUID type."""
|
460
|
+
|
461
|
+
__visit_name__ = "UUID"
|
462
|
+
|
463
|
+
@overload
|
464
|
+
def __init__(self: UUID[_python_UUID], as_uuid: Literal[True] = ...): ...
|
465
|
+
@overload
|
466
|
+
def __init__(self: UUID[str], as_uuid: Literal[False] = ...): ...
|
467
|
+
|
468
|
+
def __init__(self, as_uuid: bool = True):
|
469
|
+
self.as_uuid = as_uuid
|
470
|
+
|
471
|
+
@property
|
472
|
+
def python_type(self) -> Type[UuidType]:
|
473
|
+
return _python_UUID
|
474
|
+
|
475
|
+
|
476
|
+
# endregion
|
477
|
+
|
478
|
+
|
479
|
+
# region Basic datatypes
|
480
|
+
|
481
|
+
|
482
|
+
class NullType(TypeEngine[None]):
|
483
|
+
__visit_name__ = "null"
|
484
|
+
|
485
|
+
@property
|
486
|
+
def python_type(self) -> NoneType:
|
487
|
+
return NoneType
|
488
|
+
|
489
|
+
|
490
|
+
class INTEGER(Integer):
|
491
|
+
__visit_name__ = "INTEGER"
|
492
|
+
|
493
|
+
|
494
|
+
INT = INTEGER
|
495
|
+
|
496
|
+
|
497
|
+
class SMALLINTEGER(SmallInteger):
|
498
|
+
__visit_name__ = "SMALLINTEGER"
|
499
|
+
|
500
|
+
|
501
|
+
SMALLINT = SMALLINTEGER
|
502
|
+
|
503
|
+
|
504
|
+
class BIGINTEGER(BigInteger):
|
505
|
+
__visit_name__ = "BIGINTEGER"
|
506
|
+
|
507
|
+
|
508
|
+
BIGINT = BIGINTEGER
|
509
|
+
|
510
|
+
|
511
|
+
class NUMERIC(Numeric):
|
512
|
+
__visit_name__ = "NUMERIC"
|
513
|
+
|
514
|
+
|
515
|
+
class FLOAT(Float):
|
516
|
+
__visit_name__ = "FLOAT"
|
517
|
+
|
518
|
+
|
519
|
+
class REAL(Real):
|
520
|
+
__visit_name__ = "REAL"
|
521
|
+
|
522
|
+
|
523
|
+
class DOUBLE(Double):
|
524
|
+
__visit_name__ = "DOUBLE"
|
525
|
+
|
526
|
+
|
527
|
+
class DECIMAL[T: NumericType](Numeric[T]):
|
528
|
+
__visit_name__ = "DECIMAL"
|
529
|
+
|
530
|
+
|
531
|
+
class STRING(String):
|
532
|
+
__visit_name__ = "STRING"
|
533
|
+
|
534
|
+
|
535
|
+
class TEXT(Text):
|
536
|
+
__visit_name__ = "TEXT"
|
537
|
+
|
538
|
+
|
539
|
+
class UNICODE(Unicode):
|
540
|
+
__visit_name__ = "UNICODE"
|
541
|
+
|
542
|
+
|
543
|
+
class UNICODETEXT(UnicodeText):
|
544
|
+
__visit_name__ = "UNICODETEXT"
|
545
|
+
|
546
|
+
|
547
|
+
class CHAR(String):
|
548
|
+
__visit_name__ = "CHAR"
|
549
|
+
|
550
|
+
|
551
|
+
class NCHAR(String):
|
552
|
+
__visit_name__ = "NCHAR"
|
553
|
+
|
554
|
+
|
555
|
+
class BLOB(LargeBinary):
|
556
|
+
"""The SQL BLOB type"""
|
557
|
+
|
558
|
+
__visit_name__ = "BLOB"
|
559
|
+
|
560
|
+
|
561
|
+
class VARCHAR(String):
|
562
|
+
__visit_name__ = "VARCHAR"
|
563
|
+
|
564
|
+
|
565
|
+
class NVARCHAR(String):
|
566
|
+
__visit_name__ = "NVARCHAR"
|
567
|
+
|
568
|
+
|
569
|
+
class DATE(Date):
|
570
|
+
__visit_name__ = "DATE"
|
571
|
+
|
572
|
+
|
573
|
+
class TIME(Time):
|
574
|
+
__visit_name__ = "TIME"
|
575
|
+
|
576
|
+
|
577
|
+
class DATETIME(Datetime):
|
578
|
+
__visit_name__ = "DATETIME"
|
579
|
+
|
580
|
+
|
581
|
+
class TIMESTAMP(Timestamp):
|
582
|
+
__visit_name__ = "TIMESTAMP"
|
583
|
+
|
584
|
+
|
585
|
+
class BOOLEAN(Boolean):
|
586
|
+
__visit_name__ = "BOOLEAN"
|
587
|
+
|
588
|
+
|
589
|
+
class LARGEBINARY(LargeBinary):
|
590
|
+
__visit_name__ = "LARGEBINARY"
|
591
|
+
|
592
|
+
|
593
|
+
class VARBINARY(Varbinary):
|
594
|
+
__visit_name__ = "VARBINARY"
|
595
|
+
|
596
|
+
|
597
|
+
class ENUM(Enum):
|
598
|
+
__visit_name__ = "ENUM"
|
599
|
+
|
600
|
+
class POINT(Point):
|
601
|
+
__visit_name__ = "POINT"
|
602
|
+
|
603
|
+
|
604
|
+
NULLTYPE = NullType()
|
605
|
+
BOOLEANTYPE = Boolean()
|
606
|
+
STRINGTYPE = String()
|
607
|
+
INTEGERTYPE = Integer()
|
608
|
+
NUMERICTYPE: Numeric[decimal.Decimal] = Numeric()
|
609
|
+
DATETIME_TIMEZONE = Datetime(timezone=True)
|
610
|
+
TIME_TIMEZONE = TIME(timezone=True)
|
611
|
+
|
612
|
+
_BIGINTEGER = BigInteger()
|
613
|
+
_DATETIME = Datetime()
|
614
|
+
_TIME = Time()
|
615
|
+
_STRING = String(255, None)
|
616
|
+
_UNICODE = Unicode()
|
617
|
+
_BINARY = LargeBinary()
|
618
|
+
_ENUM = Enum(enum.Enum)
|
619
|
+
|
620
|
+
_type_dicc: dict[Any, TypeEngine[Any]] = {
|
621
|
+
str: _STRING,
|
622
|
+
int: Integer(),
|
623
|
+
float: Float(),
|
624
|
+
NoneType: NULLTYPE,
|
625
|
+
dt.datetime: Datetime(timezone=False),
|
626
|
+
bytes: _BINARY,
|
627
|
+
bytearray: _BINARY,
|
628
|
+
bool: Boolean(),
|
629
|
+
enum.Enum: _ENUM,
|
630
|
+
Literal: _ENUM,
|
631
|
+
_python_UUID: UUID(),
|
632
|
+
_python_Point: POINT()
|
633
|
+
}
|
634
|
+
# enderegion
|
635
|
+
|
636
|
+
|
637
|
+
def resolve_primitive_types[T](value: T) -> TypeEngine[T]:
|
638
|
+
if inspect.isclass(value):
|
639
|
+
type_ = _type_dicc.get(value, None)
|
640
|
+
|
641
|
+
if type_:
|
642
|
+
return type_
|
643
|
+
|
644
|
+
_result_type = _type_dicc.get(type(value), None)
|
645
|
+
if not _result_type:
|
646
|
+
return NULLTYPE
|
647
|
+
return _result_type._resolve_for_literal_value(value)
|
ormlambda/sql/table/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
from .
|
1
|
+
from .table import Table, TableMeta # noqa: F401
|