sqlmodel-ext 0.2.0__py3-none-any.whl → 0.3.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.
- sqlmodel_ext/__init__.py +31 -2
- sqlmodel_ext/_compat.py +18 -0
- sqlmodel_ext/_sa_type.py +3 -2
- sqlmodel_ext/_utils.py +3 -3
- sqlmodel_ext/base.py +613 -82
- sqlmodel_ext/field_types/__init__.py +80 -22
- sqlmodel_ext/field_types/dialects/postgresql/array.py +119 -103
- sqlmodel_ext/mixins/__init__.py +8 -0
- sqlmodel_ext/mixins/cached_table.py +2074 -0
- sqlmodel_ext/mixins/polymorphic.py +222 -35
- sqlmodel_ext/mixins/relation_preload.py +85 -35
- sqlmodel_ext/mixins/table.py +432 -106
- sqlmodel_ext/relation_load_checker.py +3645 -0
- {sqlmodel_ext-0.2.0.dist-info → sqlmodel_ext-0.3.0.dist-info}/METADATA +143 -5
- {sqlmodel_ext-0.2.0.dist-info → sqlmodel_ext-0.3.0.dist-info}/RECORD +17 -15
- {sqlmodel_ext-0.2.0.dist-info → sqlmodel_ext-0.3.0.dist-info}/WHEEL +1 -1
- {sqlmodel_ext-0.2.0.dist-info → sqlmodel_ext-0.3.0.dist-info}/licenses/LICENSE +0 -0
sqlmodel_ext/__init__.py
CHANGED
|
@@ -20,10 +20,10 @@ Quick start::
|
|
|
20
20
|
user = await user.save(session)
|
|
21
21
|
users = await User.get(session, fetch_mode="all")
|
|
22
22
|
"""
|
|
23
|
-
__version__ = "0.2.
|
|
23
|
+
__version__ = "0.2.1"
|
|
24
24
|
|
|
25
25
|
# Base
|
|
26
|
-
from sqlmodel_ext.base import SQLModelBase
|
|
26
|
+
from sqlmodel_ext.base import SQLModelBase, ExtraIgnoreModelBase
|
|
27
27
|
|
|
28
28
|
# Exceptions
|
|
29
29
|
from sqlmodel_ext._exceptions import RecordNotFoundError
|
|
@@ -39,8 +39,12 @@ from sqlmodel_ext.pagination import (
|
|
|
39
39
|
# Mixins
|
|
40
40
|
from sqlmodel_ext.mixins import (
|
|
41
41
|
# Table
|
|
42
|
+
SESSION_FOR_UPDATE_KEY,
|
|
42
43
|
TableBaseMixin,
|
|
43
44
|
UUIDTableBaseMixin,
|
|
45
|
+
rel,
|
|
46
|
+
cond,
|
|
47
|
+
safe_reset,
|
|
44
48
|
# Polymorphic
|
|
45
49
|
PolymorphicBaseMixin,
|
|
46
50
|
AutoPolymorphicIdentityMixin,
|
|
@@ -53,6 +57,9 @@ from sqlmodel_ext.mixins import (
|
|
|
53
57
|
# Relation Preload
|
|
54
58
|
RelationPreloadMixin,
|
|
55
59
|
requires_relations,
|
|
60
|
+
requires_for_update,
|
|
61
|
+
# Cached Table
|
|
62
|
+
CachedTableBaseMixin,
|
|
56
63
|
# Info Response DTOs
|
|
57
64
|
IntIdInfoMixin,
|
|
58
65
|
UUIDIdInfoMixin,
|
|
@@ -67,6 +74,7 @@ from sqlmodel_ext.field_types import (
|
|
|
67
74
|
DirectoryPathType,
|
|
68
75
|
FilePathType,
|
|
69
76
|
# String constraints
|
|
77
|
+
Str16,
|
|
70
78
|
Str24,
|
|
71
79
|
Str32,
|
|
72
80
|
Str36,
|
|
@@ -76,21 +84,33 @@ from sqlmodel_ext.field_types import (
|
|
|
76
84
|
Str128,
|
|
77
85
|
Str255,
|
|
78
86
|
Str256,
|
|
87
|
+
Str500,
|
|
88
|
+
Str512,
|
|
89
|
+
Str2048,
|
|
79
90
|
Text1K,
|
|
80
91
|
Text1024,
|
|
81
92
|
Text2K,
|
|
82
93
|
Text2500,
|
|
83
94
|
Text3K,
|
|
95
|
+
Text5K,
|
|
84
96
|
Text10K,
|
|
97
|
+
Text32K,
|
|
85
98
|
Text60K,
|
|
86
99
|
Text64K,
|
|
87
100
|
Text100K,
|
|
101
|
+
Text1M,
|
|
88
102
|
# Numeric constraints
|
|
103
|
+
INT32_MAX,
|
|
104
|
+
INT64_MAX,
|
|
105
|
+
JS_MAX_SAFE_INTEGER,
|
|
89
106
|
Port,
|
|
90
107
|
Percentage,
|
|
91
108
|
PositiveInt,
|
|
92
109
|
NonNegativeInt,
|
|
110
|
+
PositiveBigInt,
|
|
111
|
+
NonNegativeBigInt,
|
|
93
112
|
PositiveFloat,
|
|
113
|
+
NonNegativeFloat,
|
|
94
114
|
# Custom types
|
|
95
115
|
IPAddress,
|
|
96
116
|
Url,
|
|
@@ -101,3 +121,12 @@ from sqlmodel_ext.field_types import (
|
|
|
101
121
|
validate_not_private_host,
|
|
102
122
|
ModuleNameMixin,
|
|
103
123
|
)
|
|
124
|
+
|
|
125
|
+
# Relation Load Checker (static analysis)
|
|
126
|
+
from sqlmodel_ext.relation_load_checker import (
|
|
127
|
+
RelationLoadChecker,
|
|
128
|
+
RelationLoadWarning,
|
|
129
|
+
RelationLoadCheckMiddleware,
|
|
130
|
+
run_model_checks,
|
|
131
|
+
mark_app_check_completed,
|
|
132
|
+
)
|
sqlmodel_ext/_compat.py
CHANGED
|
@@ -65,7 +65,25 @@ if sys.version_info >= (3, 14):
|
|
|
65
65
|
non_none_args = [a for a in args if a is not type(None)]
|
|
66
66
|
if non_none_args:
|
|
67
67
|
first_arg = non_none_args[0]
|
|
68
|
+
# Check for Annotated SA type metadata first (e.g. Array[T] | None).
|
|
69
|
+
# Array[T] desugars to Annotated[list[T], _ArrayTypeHandler(T)];
|
|
70
|
+
# wrapping with | None produces Union[Annotated[...], None],
|
|
71
|
+
# so the SA type must be extracted from the inner Annotated.
|
|
72
|
+
first_arg_type_name = type(first_arg).__name__
|
|
73
|
+
if first_arg_type_name in ('AnnotatedAlias', '_AnnotatedAlias'):
|
|
74
|
+
inner_args = get_args(first_arg)
|
|
75
|
+
for md in inner_args[1:]:
|
|
76
|
+
if hasattr(md, '__get_pydantic_core_schema__'):
|
|
77
|
+
try:
|
|
78
|
+
schema = md.__get_pydantic_core_schema__(None, None)
|
|
79
|
+
if isinstance(schema, dict) and 'metadata' in schema:
|
|
80
|
+
sa_type = schema['metadata'].get('sa_type')
|
|
81
|
+
if sa_type is not None:
|
|
82
|
+
return sa_type
|
|
83
|
+
except (TypeError, AttributeError, KeyError):
|
|
84
|
+
pass
|
|
68
85
|
first_origin = get_origin(first_arg)
|
|
86
|
+
# Plain list/dict/tuple/set (no Annotated SA type) -> JSONB
|
|
69
87
|
if first_origin in (list, dict, tuple, set):
|
|
70
88
|
return JSONB
|
|
71
89
|
|
sqlmodel_ext/_sa_type.py
CHANGED
|
@@ -97,7 +97,8 @@ def _resolve_annotations(attrs: dict[str, Any]) -> tuple[
|
|
|
97
97
|
|
|
98
98
|
try:
|
|
99
99
|
temp_cls = type('AnnotationProxy', (object,), dict(attrs))
|
|
100
|
-
|
|
100
|
+
if isinstance(module_name, str):
|
|
101
|
+
temp_cls.__module__ = module_name
|
|
101
102
|
extras_kw = {'include_extras': True} if sys.version_info >= (3, 10) else {}
|
|
102
103
|
evaluated = get_type_hints(
|
|
103
104
|
temp_cls,
|
|
@@ -132,6 +133,6 @@ def _evaluate_annotation_from_string(
|
|
|
132
133
|
return current_type
|
|
133
134
|
|
|
134
135
|
try:
|
|
135
|
-
return eval(expr, globalns, localns)
|
|
136
|
+
return eval(expr, dict(globalns), dict(localns))
|
|
136
137
|
except (NameError, SyntaxError, AttributeError, TypeError):
|
|
137
138
|
return current_type
|
sqlmodel_ext/_utils.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""Internal utility functions."""
|
|
2
|
-
from datetime import datetime
|
|
2
|
+
from datetime import datetime, timezone
|
|
3
3
|
|
|
4
|
-
now = lambda: datetime.now()
|
|
5
|
-
now_date = lambda: datetime.now().date()
|
|
4
|
+
now = lambda: datetime.now(timezone.utc)
|
|
5
|
+
now_date = lambda: datetime.now(timezone.utc).date()
|