f3-data-models 0.3.7__tar.gz → 0.4.0__tar.gz
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.
- {f3_data_models-0.3.7 → f3_data_models-0.4.0}/PKG-INFO +1 -1
- {f3_data_models-0.3.7 → f3_data_models-0.4.0}/f3_data_models/models.py +41 -14
- {f3_data_models-0.3.7 → f3_data_models-0.4.0}/f3_data_models/testing.py +6 -12
- {f3_data_models-0.3.7 → f3_data_models-0.4.0}/f3_data_models/utils.py +8 -6
- {f3_data_models-0.3.7 → f3_data_models-0.4.0}/pyproject.toml +1 -1
- {f3_data_models-0.3.7 → f3_data_models-0.4.0}/README.md +0 -0
- {f3_data_models-0.3.7 → f3_data_models-0.4.0}/f3_data_models/__init__.py +0 -0
@@ -1,6 +1,5 @@
|
|
1
1
|
from datetime import datetime, date, time
|
2
2
|
from typing import Any, Dict, List, Optional
|
3
|
-
import uuid
|
4
3
|
from sqlalchemy import (
|
5
4
|
ARRAY,
|
6
5
|
JSON,
|
@@ -17,6 +16,7 @@ from sqlalchemy import (
|
|
17
16
|
UniqueConstraint,
|
18
17
|
Enum,
|
19
18
|
Uuid,
|
19
|
+
inspect,
|
20
20
|
)
|
21
21
|
from typing_extensions import Annotated
|
22
22
|
from sqlalchemy.orm import (
|
@@ -25,11 +25,13 @@ from sqlalchemy.orm import (
|
|
25
25
|
Mapped,
|
26
26
|
relationship,
|
27
27
|
)
|
28
|
+
from sqlalchemy.orm.attributes import InstrumentedAttribute
|
28
29
|
import enum
|
29
30
|
|
30
31
|
# Custom Annotations
|
31
32
|
time_notz = Annotated[time, TIME(timezone=False)]
|
32
33
|
time_with_tz = Annotated[time, TIME(timezone=True)]
|
34
|
+
ts_notz = Annotated[datetime, DateTime(timezone=False)]
|
33
35
|
text = Annotated[str, TEXT]
|
34
36
|
intpk = Annotated[int, mapped_column(Integer, primary_key=True, autoincrement=True)]
|
35
37
|
dt_create = Annotated[
|
@@ -150,6 +152,26 @@ class Base(DeclarativeBase):
|
|
150
152
|
if c.key not in ["created", "updated"]
|
151
153
|
}
|
152
154
|
|
155
|
+
def to_update_dict(self) -> Dict[InstrumentedAttribute, Any]:
|
156
|
+
update_dict = {}
|
157
|
+
mapper = inspect(self).mapper
|
158
|
+
|
159
|
+
# Add simple attributes
|
160
|
+
for attr in mapper.column_attrs:
|
161
|
+
if attr.key not in ["created", "updated", "id"]:
|
162
|
+
update_dict[attr] = getattr(self, attr.key)
|
163
|
+
|
164
|
+
# Add relationships
|
165
|
+
for rel in mapper.relationships:
|
166
|
+
related_value = getattr(self, rel.key)
|
167
|
+
if related_value is not None:
|
168
|
+
if rel.uselist:
|
169
|
+
update_dict[rel] = [item for item in related_value]
|
170
|
+
print(rel, update_dict[rel])
|
171
|
+
else:
|
172
|
+
update_dict[rel] = related_value
|
173
|
+
return update_dict
|
174
|
+
|
153
175
|
def __repr__(self):
|
154
176
|
"""
|
155
177
|
Get a string representation of the model instance.
|
@@ -641,10 +663,13 @@ class Event(Base):
|
|
641
663
|
secondary="event_tags_x_events", cascade="expunge", viewonly=True
|
642
664
|
)
|
643
665
|
event_x_event_types: Mapped[List[EventType_x_Event]] = relationship(
|
644
|
-
back_populates="event"
|
666
|
+
back_populates="event", cascade="save-update, merge, delete"
|
645
667
|
)
|
646
668
|
event_x_event_tags: Mapped[Optional[List[EventTag_x_Event]]] = relationship(
|
647
|
-
back_populates="event"
|
669
|
+
back_populates="event", cascade="save-update, merge, delete"
|
670
|
+
)
|
671
|
+
attendance: Mapped[List["Attendance"]] = relationship(
|
672
|
+
back_populates="event", cascade="expunge, delete"
|
648
673
|
)
|
649
674
|
|
650
675
|
|
@@ -819,7 +844,7 @@ class Attendance(Base):
|
|
819
844
|
innerjoin=False, cascade="expunge", secondary="users", viewonly=True
|
820
845
|
)
|
821
846
|
attendance_x_attendance_types: Mapped[List[Attendance_x_AttendanceType]] = (
|
822
|
-
relationship(back_populates="attendance")
|
847
|
+
relationship(back_populates="attendance", cascade="save-update, merge, delete")
|
823
848
|
)
|
824
849
|
attendance_types: Mapped[List[AttendanceType]] = relationship(
|
825
850
|
secondary="attendance_x_attendance_types",
|
@@ -980,7 +1005,7 @@ class NextAuthAccount(Base):
|
|
980
1005
|
provider (text): The provider of the account.
|
981
1006
|
provider_account_id (text): The provider account ID.
|
982
1007
|
refresh_token (Optional[text]): The refresh token.
|
983
|
-
access_token (text): The access token.
|
1008
|
+
access_token (Optional[text]): The access token.
|
984
1009
|
expires_at (Optional[datetime]): The expiration time of the token.
|
985
1010
|
token_type (Optional[text]): The token type.
|
986
1011
|
scope (Optional[text]): The scope of the token.
|
@@ -997,7 +1022,7 @@ class NextAuthAccount(Base):
|
|
997
1022
|
provider: Mapped[text] = mapped_column(VARCHAR, primary_key=True)
|
998
1023
|
provider_account_id: Mapped[text] = mapped_column(VARCHAR, primary_key=True)
|
999
1024
|
refresh_token: Mapped[Optional[text]]
|
1000
|
-
access_token: Mapped[text]
|
1025
|
+
access_token: Mapped[Optional[text]]
|
1001
1026
|
expires_at: Mapped[Optional[datetime]]
|
1002
1027
|
token_type: Mapped[Optional[text]]
|
1003
1028
|
scope: Mapped[Optional[text]]
|
@@ -1014,7 +1039,7 @@ class NextAuthSession(Base):
|
|
1014
1039
|
Attributes:
|
1015
1040
|
session_token (text): The session token.
|
1016
1041
|
user_id (int): The ID of the associated user.
|
1017
|
-
expires (
|
1042
|
+
expires (ts_notz): The expiration time of the session.
|
1018
1043
|
created (datetime): The timestamp when the record was created.
|
1019
1044
|
updated (datetime): The timestamp when the record was last updated.
|
1020
1045
|
"""
|
@@ -1022,8 +1047,8 @@ class NextAuthSession(Base):
|
|
1022
1047
|
__tablename__ = "auth_sessions"
|
1023
1048
|
|
1024
1049
|
session_token: Mapped[text] = mapped_column(TEXT, primary_key=True)
|
1025
|
-
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
|
1026
|
-
expires: Mapped[
|
1050
|
+
user_id: Mapped[int] = mapped_column(ForeignKey("users.id", ondelete="CASCADE"))
|
1051
|
+
expires: Mapped[ts_notz]
|
1027
1052
|
created: Mapped[dt_create]
|
1028
1053
|
updated: Mapped[dt_update]
|
1029
1054
|
|
@@ -1035,7 +1060,7 @@ class NextAuthVerificationToken(Base):
|
|
1035
1060
|
Attributes:
|
1036
1061
|
identifier (text): The identifier of the token.
|
1037
1062
|
token (text): The token.
|
1038
|
-
expires (
|
1063
|
+
expires (ts_notz): The expiration time of the token.
|
1039
1064
|
created (datetime): The timestamp when the record was created.
|
1040
1065
|
updated (datetime): The timestamp when the record was last updated.
|
1041
1066
|
"""
|
@@ -1044,7 +1069,7 @@ class NextAuthVerificationToken(Base):
|
|
1044
1069
|
|
1045
1070
|
identifier: Mapped[text] = mapped_column(VARCHAR, primary_key=True)
|
1046
1071
|
token: Mapped[text] = mapped_column(VARCHAR, primary_key=True)
|
1047
|
-
expires: Mapped[
|
1072
|
+
expires: Mapped[ts_notz]
|
1048
1073
|
created: Mapped[dt_create]
|
1049
1074
|
updated: Mapped[dt_update]
|
1050
1075
|
|
@@ -1071,7 +1096,7 @@ class UpdateRequest(Base):
|
|
1071
1096
|
event_day_of_week (Optional[Day_Of_Week]): The day of the week of the event.
|
1072
1097
|
event_name (str): The name of the event.
|
1073
1098
|
event_description (Optional[text]): A description of the event.
|
1074
|
-
event_recurrence_pattern (Optional[
|
1099
|
+
event_recurrence_pattern (Optional[Event_Cadence]): The recurrence pattern of the event.
|
1075
1100
|
event_recurrence_interval (Optional[int]): The recurrence interval of the event.
|
1076
1101
|
event_index_within_interval (Optional[int]): The index within the recurrence interval.
|
1077
1102
|
event_meta (Optional[Dict[str, Any]]): Additional metadata for the event.
|
@@ -1102,7 +1127,9 @@ class UpdateRequest(Base):
|
|
1102
1127
|
__tablename__ = "update_requests"
|
1103
1128
|
|
1104
1129
|
id: Mapped[Uuid] = mapped_column(UUID(as_uuid=True), primary_key=True)
|
1105
|
-
token: Mapped[Uuid] = mapped_column(
|
1130
|
+
token: Mapped[Uuid] = mapped_column(
|
1131
|
+
UUID(as_uuid=True), server_default=func.gen_random_uuid()
|
1132
|
+
)
|
1106
1133
|
region_id: Mapped[int] = mapped_column(ForeignKey("orgs.id"))
|
1107
1134
|
event_id: Mapped[Optional[int]] = mapped_column(ForeignKey("events.id"))
|
1108
1135
|
event_type_ids: Mapped[Optional[List[int]]] = mapped_column(ARRAY(Integer))
|
@@ -1118,7 +1145,7 @@ class UpdateRequest(Base):
|
|
1118
1145
|
event_day_of_week: Mapped[Optional[Day_Of_Week]]
|
1119
1146
|
event_name: Mapped[str]
|
1120
1147
|
event_description: Mapped[Optional[text]]
|
1121
|
-
event_recurrence_pattern: Mapped[Optional[
|
1148
|
+
event_recurrence_pattern: Mapped[Optional[Event_Cadence]]
|
1122
1149
|
event_recurrence_interval: Mapped[Optional[int]]
|
1123
1150
|
event_index_within_interval: Mapped[Optional[int]]
|
1124
1151
|
event_meta: Mapped[Optional[Dict[str, Any]]]
|
@@ -12,10 +12,10 @@ def test_update_event():
|
|
12
12
|
highlight=True,
|
13
13
|
start_date=datetime.date(2025, 2, 17),
|
14
14
|
end_date=datetime.date(2026, 2, 17),
|
15
|
-
start_time="
|
15
|
+
start_time="0400",
|
16
16
|
end_time="0600",
|
17
17
|
event_x_event_types=[
|
18
|
-
EventType_x_Event(event_type_id=
|
18
|
+
EventType_x_Event(event_type_id=3),
|
19
19
|
],
|
20
20
|
recurrence_pattern=Event_Cadence.weekly,
|
21
21
|
day_of_week=Day_Of_Week.monday,
|
@@ -23,17 +23,11 @@ def test_update_event():
|
|
23
23
|
index_within_interval=1,
|
24
24
|
name="Test Event",
|
25
25
|
)
|
26
|
-
update_dict = event.
|
27
|
-
DbManager.
|
26
|
+
update_dict = event.to_update_dict()
|
27
|
+
DbManager.update_record(Event, 3, update_dict)
|
28
28
|
|
29
|
-
#
|
30
|
-
|
31
|
-
# session.query(EventType_x_Event).filter(
|
32
|
-
# EventType_x_Event.event_id == 3
|
33
|
-
# ).delete()
|
34
|
-
# # add event_x_event_types
|
35
|
-
# session.add(EventType_x_Event(event_id=3, event_type_id=4))
|
36
|
-
# session.commit()
|
29
|
+
# event = DbManager.get(Event, 3)
|
30
|
+
DbManager.delete_records(Event, [Event.series_id == 3])
|
37
31
|
|
38
32
|
|
39
33
|
if __name__ == "__main__":
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import os
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import List, Optional, Tuple, TypeVar
|
3
|
+
from typing import List, Optional, Tuple, TypeVar, Type, Generic # noqa
|
4
4
|
|
5
5
|
import sqlalchemy
|
6
6
|
from sqlalchemy import Select, and_, select, inspect
|
@@ -89,7 +89,7 @@ def _joinedloads(cls: T, query: Select, joinedloads: list | str) -> Select:
|
|
89
89
|
|
90
90
|
|
91
91
|
class DbManager:
|
92
|
-
def get(cls: T, id: int, joinedloads: list | str = []) -> T:
|
92
|
+
def get(cls: Type[T], id: int, joinedloads: list | str = []) -> T:
|
93
93
|
session = get_session()
|
94
94
|
try:
|
95
95
|
query = select(cls).filter(cls.id == id)
|
@@ -175,9 +175,9 @@ class DbManager:
|
|
175
175
|
|
176
176
|
mapper = class_mapper(cls)
|
177
177
|
relationships = mapper.relationships.keys()
|
178
|
-
for
|
178
|
+
for attr, value in fields.items():
|
179
|
+
key = attr.key
|
179
180
|
if hasattr(cls, key) and key not in relationships:
|
180
|
-
attr = getattr(cls, key)
|
181
181
|
if isinstance(attr, InstrumentedAttribute):
|
182
182
|
setattr(record, key, value)
|
183
183
|
elif key in relationships:
|
@@ -232,14 +232,16 @@ class DbManager:
|
|
232
232
|
|
233
233
|
for obj in objects:
|
234
234
|
# Update simple fields
|
235
|
-
for
|
235
|
+
for attr, value in fields.items():
|
236
|
+
key = attr.key
|
236
237
|
if key in valid_attributes and not isinstance(
|
237
238
|
value, InstrumentedList
|
238
239
|
):
|
239
240
|
setattr(obj, key, value)
|
240
241
|
|
241
242
|
# Update relationships separately
|
242
|
-
for
|
243
|
+
for attr, value in fields.items():
|
244
|
+
key = attr.key
|
243
245
|
if key in valid_relationships:
|
244
246
|
# Handle relationships separately
|
245
247
|
relationship = inspect(cls).mapper.relationships[key]
|
File without changes
|
File without changes
|