sera-2 1.19.0__py3-none-any.whl → 1.19.2__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.
- sera/make/make_python_model.py +21 -4
- sera/make/make_typescript_model.py +17 -7
- sera/misc/_utils.py +12 -0
- sera/models/_collection.py +12 -2
- sera/typing.py +1 -0
- {sera_2-1.19.0.dist-info → sera_2-1.19.2.dist-info}/METADATA +1 -1
- {sera_2-1.19.0.dist-info → sera_2-1.19.2.dist-info}/RECORD +8 -8
- {sera_2-1.19.0.dist-info → sera_2-1.19.2.dist-info}/WHEEL +0 -0
sera/make/make_python_model.py
CHANGED
@@ -146,7 +146,11 @@ def make_python_data_model(
|
|
146
146
|
mode: Literal["create", "update"],
|
147
147
|
prop: DataProperty | ObjectProperty,
|
148
148
|
):
|
149
|
-
|
149
|
+
if isinstance(prop, ObjectProperty) and prop.target.db is not None:
|
150
|
+
propname = prop.name + "_id"
|
151
|
+
else:
|
152
|
+
propname = prop.name
|
153
|
+
value = PredefinedFn.attr_getter(slf, expr.ExprIdent(propname))
|
150
154
|
if isinstance(prop, ObjectProperty):
|
151
155
|
if (
|
152
156
|
prop.target.db is not None
|
@@ -421,12 +425,14 @@ def make_python_data_model(
|
|
421
425
|
elif isinstance(prop, ObjectProperty):
|
422
426
|
if prop.target.db is not None:
|
423
427
|
# if the target class is in the database, we expect the user to pass the foreign key for it.
|
428
|
+
propname = prop.name + "_id"
|
424
429
|
pytype = (
|
425
430
|
assert_not_null(prop.target.get_id_property())
|
426
431
|
.get_data_model_datatype()
|
427
432
|
.get_python_type()
|
428
433
|
)
|
429
434
|
else:
|
435
|
+
propname = prop.name
|
430
436
|
pytype = PyTypeWithDep(
|
431
437
|
f"Create{prop.target.name}",
|
432
438
|
[
|
@@ -442,7 +448,7 @@ def make_python_data_model(
|
|
442
448
|
for dep in pytype.deps:
|
443
449
|
program.import_(dep, True)
|
444
450
|
|
445
|
-
cls_ast(stmt.DefClassVarStatement(
|
451
|
+
cls_ast(stmt.DefClassVarStatement(propname, pytype.type))
|
446
452
|
|
447
453
|
if is_on_create_value_updated:
|
448
454
|
program.import_("typing.Optional", True)
|
@@ -604,13 +610,16 @@ def make_python_data_model(
|
|
604
610
|
)
|
605
611
|
elif isinstance(prop, ObjectProperty):
|
606
612
|
if prop.target.db is not None:
|
613
|
+
propname = prop.name + "_id"
|
607
614
|
# if the target class is in the database, we expect the user to pass the foreign key for it.
|
608
615
|
pytype = (
|
609
616
|
assert_not_null(prop.target.get_id_property())
|
610
617
|
.get_data_model_datatype()
|
611
618
|
.get_python_type()
|
612
619
|
)
|
620
|
+
|
613
621
|
else:
|
622
|
+
propname = prop.name
|
614
623
|
pytype = PyTypeWithDep(
|
615
624
|
f"Update{prop.target.name}",
|
616
625
|
[
|
@@ -626,7 +635,7 @@ def make_python_data_model(
|
|
626
635
|
for dep in pytype.deps:
|
627
636
|
program.import_(dep, True)
|
628
637
|
|
629
|
-
cls_ast(stmt.DefClassVarStatement(
|
638
|
+
cls_ast(stmt.DefClassVarStatement(propname, pytype.type))
|
630
639
|
|
631
640
|
if is_on_update_value_updated:
|
632
641
|
program.import_("typing.Optional", True)
|
@@ -720,6 +729,12 @@ def make_python_data_model(
|
|
720
729
|
|
721
730
|
program.import_("__future__.annotations", True)
|
722
731
|
program.import_("msgspec", False)
|
732
|
+
|
733
|
+
ident_manager = ImportHelper(
|
734
|
+
program,
|
735
|
+
GLOBAL_IDENTS,
|
736
|
+
)
|
737
|
+
|
723
738
|
if cls.db is not None:
|
724
739
|
# if the class is stored in the database, we need to import the database module
|
725
740
|
program.import_(
|
@@ -824,7 +839,9 @@ def make_python_data_model(
|
|
824
839
|
lambda ast: ast.func(
|
825
840
|
"as_composite",
|
826
841
|
vars=as_composite_args,
|
827
|
-
return_type=
|
842
|
+
return_type=PredefinedFn.item_getter(
|
843
|
+
ident_manager.use("Optional"), expr.ExprIdent(cls.name)
|
844
|
+
),
|
828
845
|
comment="Create an embedded instance from the embedded columns in the database table. If all properties of this embedded class are None (indicating that the parent field is None), then this function will return None.",
|
829
846
|
)(
|
830
847
|
lambda ast_l1: ast_l1.if_(
|
@@ -98,6 +98,7 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
|
|
98
98
|
assert isinstance(prop, ObjectProperty)
|
99
99
|
if prop.target.db is not None:
|
100
100
|
# this class is stored in the database, we store the id instead
|
101
|
+
propname = propname + "Id"
|
101
102
|
tstype = TsTypeWithDep(
|
102
103
|
f"{prop.target.name}Id",
|
103
104
|
[
|
@@ -113,7 +114,8 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
|
|
113
114
|
(
|
114
115
|
expr.ExprIdent(propname),
|
115
116
|
PredefinedFn.attr_getter(
|
116
|
-
expr.ExprIdent("data"),
|
117
|
+
expr.ExprIdent("data"),
|
118
|
+
expr.ExprIdent(prop.name + "_id"),
|
117
119
|
),
|
118
120
|
)
|
119
121
|
)
|
@@ -300,6 +302,8 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
|
|
300
302
|
# continue
|
301
303
|
|
302
304
|
propname = to_camel_case(prop.name)
|
305
|
+
if isinstance(prop, ObjectProperty) and prop.target.db is not None:
|
306
|
+
propname = propname + "Id"
|
303
307
|
prop2tsname[prop.name] = propname
|
304
308
|
|
305
309
|
def _update_field_func(
|
@@ -544,7 +548,7 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
|
|
544
548
|
)
|
545
549
|
ser_args.append(
|
546
550
|
(
|
547
|
-
expr.ExprIdent(prop.name),
|
551
|
+
expr.ExprIdent(prop.name + "_id"),
|
548
552
|
PredefinedFn.attr_getter(
|
549
553
|
expr.ExprIdent("this"), expr.ExprIdent(propname)
|
550
554
|
),
|
@@ -784,7 +788,7 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
|
|
784
788
|
)
|
785
789
|
)
|
786
790
|
|
787
|
-
# TODO: fix me!
|
791
|
+
# TODO: fix me! fix me what?? next time give more context.
|
788
792
|
prop_validators.append(
|
789
793
|
(
|
790
794
|
expr.ExprIdent(propname),
|
@@ -1079,12 +1083,18 @@ def make_typescript_data_model(schema: Schema, target_pkg: Package):
|
|
1079
1083
|
|
1080
1084
|
query_args = []
|
1081
1085
|
for prop in cls.properties.values():
|
1082
|
-
|
1083
|
-
|
1086
|
+
pypropname = prop.name
|
1087
|
+
tspropname = to_camel_case(prop.name)
|
1088
|
+
|
1089
|
+
if isinstance(prop, ObjectProperty) and prop.target.db is not None:
|
1090
|
+
tspropname = tspropname + "Id"
|
1091
|
+
pypropname = prop.name + "_id"
|
1092
|
+
|
1093
|
+
if tspropname != pypropname:
|
1084
1094
|
query_args.append(
|
1085
1095
|
(
|
1086
|
-
expr.ExprIdent(
|
1087
|
-
expr.ExprConstant(
|
1096
|
+
expr.ExprIdent(tspropname),
|
1097
|
+
expr.ExprConstant(pypropname),
|
1088
1098
|
)
|
1089
1099
|
)
|
1090
1100
|
|
sera/misc/_utils.py
CHANGED
@@ -191,6 +191,18 @@ def load_data(
|
|
191
191
|
|
192
192
|
# Reset the sequence for each table
|
193
193
|
for tbl in tbls:
|
194
|
+
# Check if the table has an auto-incrementing primary key
|
195
|
+
if not hasattr(tbl, "__table__") or not tbl.__table__.primary_key:
|
196
|
+
continue
|
197
|
+
|
198
|
+
pk_columns = tbl.__table__.primary_key.columns
|
199
|
+
has_foreign_key = any(len(col.foreign_keys) > 0 for col in pk_columns)
|
200
|
+
has_auto_increment = any(
|
201
|
+
col.autoincrement and col.type.python_type in (int,)
|
202
|
+
for col in pk_columns
|
203
|
+
)
|
204
|
+
if has_foreign_key or not has_auto_increment:
|
205
|
+
continue
|
194
206
|
session.execute(
|
195
207
|
text(
|
196
208
|
f"SELECT setval('{tbl.__tablename__}_id_seq', (SELECT MAX(id) FROM \"{tbl.__tablename__}\"));"
|
sera/models/_collection.py
CHANGED
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
3
3
|
from dataclasses import dataclass
|
4
4
|
|
5
5
|
from sera.models._class import Class
|
6
|
-
from sera.models._property import DataProperty
|
6
|
+
from sera.models._property import DataProperty, ObjectProperty
|
7
7
|
|
8
8
|
|
9
9
|
@dataclass
|
@@ -35,7 +35,17 @@ class DataCollection:
|
|
35
35
|
):
|
36
36
|
# This property is not indexed, so we skip it
|
37
37
|
continue
|
38
|
-
|
38
|
+
if isinstance(prop, ObjectProperty) and prop.target.db is None:
|
39
|
+
# TODO: Implement this! This property is an embedded object property, we need to figure out
|
40
|
+
# which necessary properties are queryable and add them to the field names
|
41
|
+
continue
|
42
|
+
if isinstance(prop, ObjectProperty) and prop.target.db is not None:
|
43
|
+
# This property is an object property stored in the database, "_id" is added to the property name
|
44
|
+
propname = prop.name + "_id"
|
45
|
+
else:
|
46
|
+
# This property is a data property or an object property not stored in the database, so we use its name
|
47
|
+
propname = prop.name
|
48
|
+
field_names.add(propname)
|
39
49
|
return field_names
|
40
50
|
|
41
51
|
def get_service_name(self):
|
sera/typing.py
CHANGED
@@ -23,15 +23,15 @@ sera/make/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
23
|
sera/make/__main__.py,sha256=HRfOR53p351h6KblVvYm3DLhDIfEtk6R0kjl78_S_S8,1453
|
24
24
|
sera/make/make_app.py,sha256=n9NtW73O3s_5Q31VHIRmnd-jEIcpDO7ksAsOdovde2s,5999
|
25
25
|
sera/make/make_python_api.py,sha256=iXGbKQ3IJvsY1ur_fhurr_THFNnH66E3Wl85o0emUbw,26853
|
26
|
-
sera/make/make_python_model.py,sha256=
|
26
|
+
sera/make/make_python_model.py,sha256=3qz1OUg2n4QPt31mZHMncU5v9riXUAoQwIpXCa4Fyv4,63306
|
27
27
|
sera/make/make_python_services.py,sha256=0ZpWLwQ7Nwfn8BXAikAB4JRpNknpSJyJgY5b1cjtxV4,2073
|
28
|
-
sera/make/make_typescript_model.py,sha256=
|
28
|
+
sera/make/make_typescript_model.py,sha256=laW27gFYGFhvLY5DfcVgh8tPlDqvmS824r-fbBnG7JI,67493
|
29
29
|
sera/misc/__init__.py,sha256=rOmGMv7QNzpSKZSyxChbRmEnBr3O443UlLGS0FIs3AI,561
|
30
30
|
sera/misc/_formatter.py,sha256=aCGYL08l8f3aLODHxSocxBBwkRYEo3K1QzCDEn3suj0,1685
|
31
|
-
sera/misc/_utils.py,sha256=
|
31
|
+
sera/misc/_utils.py,sha256=_-17XbK6qp3HobcI9iLF4xfaATvFg1ckUzgg7r7Ctmw,7135
|
32
32
|
sera/models/__init__.py,sha256=vJC5Kzo_N7wd16ocNPy1VvAZDGNiWeiAhWJ4ihATKvA,780
|
33
33
|
sera/models/_class.py,sha256=1J4Bd_LanzhhDWwZFHWGtFYD7lupe_alaB3D02ebNDI,2862
|
34
|
-
sera/models/_collection.py,sha256=
|
34
|
+
sera/models/_collection.py,sha256=AmEy6SoTTaxqFU4mBFVfFMGyutJuNnUGBaIV7xzGxbc,2143
|
35
35
|
sera/models/_constraints.py,sha256=RpWDU-TfCslXaMUaTG9utWbl5z8Z6nzvF_fhqlek6ew,1987
|
36
36
|
sera/models/_datatype.py,sha256=cC6Wm0IvobDF5Tq9Jy_ncbjPWBRl3ECGBy0wJyDDMzU,7281
|
37
37
|
sera/models/_default.py,sha256=ABggW6qdPR4ZDqIPJdJ0GCGQ-7kfsfZmQ_DchgZEa-I,137
|
@@ -41,7 +41,7 @@ sera/models/_multi_lingual_string.py,sha256=JETN6k00VH4wrA4w5vAHMEJV8fp3SY9bJebs
|
|
41
41
|
sera/models/_parse.py,sha256=ciTLzCkO0q6xA1R_rHbnYJYK3Duo2oh56WeuwxXwJaI,12392
|
42
42
|
sera/models/_property.py,sha256=9yMDxrmbyuF6-29lQjiq163Xzwbk75TlmGBpu0NLpkI,7485
|
43
43
|
sera/models/_schema.py,sha256=VxJEiqgVvbXgcSUK4UW6JnRcggk4nsooVSE6MyXmfNY,1636
|
44
|
-
sera/typing.py,sha256=
|
45
|
-
sera_2-1.19.
|
46
|
-
sera_2-1.19.
|
47
|
-
sera_2-1.19.
|
44
|
+
sera/typing.py,sha256=m4rir-fB6Cgcm7_ZSXXcNdla2LJgq96WXxtTTrDaJno,1058
|
45
|
+
sera_2-1.19.2.dist-info/METADATA,sha256=yv6pv0XvFLzt1CqYP5u38CCVGHLInOCB1AflthDV5_g,936
|
46
|
+
sera_2-1.19.2.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
47
|
+
sera_2-1.19.2.dist-info/RECORD,,
|
File without changes
|