f3-data-models 0.1.0__tar.gz → 0.1.3__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.1.0 → f3_data_models-0.1.3}/PKG-INFO +2 -1
- {f3_data_models-0.1.0 → f3_data_models-0.1.3}/f3_data_models/models.py +111 -44
- {f3_data_models-0.1.0 → f3_data_models-0.1.3}/f3_data_models/utils.py +28 -9
- {f3_data_models-0.1.0 → f3_data_models-0.1.3}/pyproject.toml +1 -1
- {f3_data_models-0.1.0 → f3_data_models-0.1.3}/README.md +0 -0
- {f3_data_models-0.1.0 → f3_data_models-0.1.3}/f3_data_models/__init__.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: f3-data-models
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.3
|
4
4
|
Summary: The data schema and models for F3 Nation applications.
|
5
5
|
Home-page: https://github.com/F3-Nation/f3-data-models
|
6
6
|
License: MIT
|
@@ -10,6 +10,7 @@ Requires-Python: >=3.12,<4.0
|
|
10
10
|
Classifier: License :: OSI Approved :: MIT License
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
12
12
|
Classifier: Programming Language :: Python :: 3.12
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
13
14
|
Requires-Dist: alembic (>=1.14.0,<2.0.0)
|
14
15
|
Requires-Dist: cloud-sql-python-connector (>=1.13.0,<2.0.0)
|
15
16
|
Requires-Dist: graphviz (>=0.20.3,<0.21.0)
|
@@ -118,6 +118,7 @@ class SlackSpace(Base):
|
|
118
118
|
settings (Optional[Dict[str, Any]]): Slack Bot settings for the Slack workspace.
|
119
119
|
|
120
120
|
org_x_slack (Org_x_Slack): The organization associated with this Slack workspace.
|
121
|
+
org (Org): The organization associated with this Slack workspace.
|
121
122
|
"""
|
122
123
|
|
123
124
|
__tablename__ = "slack_spaces"
|
@@ -128,6 +129,9 @@ class SlackSpace(Base):
|
|
128
129
|
settings: Mapped[Optional[Dict[str, Any]]]
|
129
130
|
|
130
131
|
org_x_slack: Mapped["Org_x_Slack"] = relationship(back_populates="slack_space")
|
132
|
+
org: Mapped["Org"] = relationship(
|
133
|
+
back_populates="slack_space", secondary="org_x_slack", lazy="joined"
|
134
|
+
)
|
131
135
|
|
132
136
|
|
133
137
|
class OrgType(Base):
|
@@ -214,9 +218,11 @@ class Role_x_Permission(Base):
|
|
214
218
|
role_id: Mapped[int] = mapped_column(ForeignKey("roles.id"))
|
215
219
|
permission_id: Mapped[int] = mapped_column(ForeignKey("permissions.id"))
|
216
220
|
|
217
|
-
role: Mapped["Role"] = relationship(
|
221
|
+
role: Mapped["Role"] = relationship(
|
222
|
+
back_populates="role_x_permission", lazy="joined"
|
223
|
+
)
|
218
224
|
permissions: Mapped[List["Permission"]] = relationship(
|
219
|
-
back_populates="role_x_permission"
|
225
|
+
back_populates="role_x_permission", lazy="joined"
|
220
226
|
)
|
221
227
|
|
222
228
|
|
@@ -242,9 +248,13 @@ class Role_x_User_x_Org(Base):
|
|
242
248
|
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
|
243
249
|
org_id: Mapped[int] = mapped_column(ForeignKey("orgs.id"))
|
244
250
|
|
245
|
-
role: Mapped["Role"] = relationship(
|
246
|
-
|
247
|
-
|
251
|
+
role: Mapped["Role"] = relationship(
|
252
|
+
back_populates="role_x_user_x_org", lazy="joined"
|
253
|
+
)
|
254
|
+
user: Mapped["User"] = relationship(
|
255
|
+
back_populates="role_x_user_x_org", lazy="joined"
|
256
|
+
)
|
257
|
+
org: Mapped["Org"] = relationship(back_populates="role_x_user_x_org", lazy="joined")
|
248
258
|
|
249
259
|
|
250
260
|
class Org(Base):
|
@@ -294,7 +304,9 @@ class Org(Base):
|
|
294
304
|
child_orgs: Mapped[List["Org"]] = relationship(
|
295
305
|
"Org", back_populates="parent_org", join_depth=3
|
296
306
|
)
|
297
|
-
locations: Mapped[List["Location"]] = relationship(
|
307
|
+
locations: Mapped[List["Location"]] = relationship(
|
308
|
+
back_populates="org", lazy="joined"
|
309
|
+
)
|
298
310
|
|
299
311
|
|
300
312
|
class EventType(Base):
|
@@ -316,7 +328,9 @@ class EventType(Base):
|
|
316
328
|
acronyms: Mapped[Optional[str]]
|
317
329
|
category_id: Mapped[int] = mapped_column(ForeignKey("event_categories.id"))
|
318
330
|
|
319
|
-
event_category: Mapped["EventCategory"] = relationship(
|
331
|
+
event_category: Mapped["EventCategory"] = relationship(
|
332
|
+
back_populates="event_types", lazy="joined"
|
333
|
+
)
|
320
334
|
|
321
335
|
|
322
336
|
class EventType_x_Event(Base):
|
@@ -338,9 +352,11 @@ class EventType_x_Event(Base):
|
|
338
352
|
event_id: Mapped[int] = mapped_column(ForeignKey("events.id"))
|
339
353
|
event_type_id: Mapped[int] = mapped_column(ForeignKey("event_types.id"))
|
340
354
|
|
341
|
-
event: Mapped["Event"] = relationship(
|
355
|
+
event: Mapped["Event"] = relationship(
|
356
|
+
back_populates="events_x_event_types", lazy="joined"
|
357
|
+
)
|
342
358
|
event_type: Mapped["EventType"] = relationship(
|
343
|
-
back_populates="events_x_event_types"
|
359
|
+
back_populates="events_x_event_types", lazy="joined"
|
344
360
|
)
|
345
361
|
|
346
362
|
|
@@ -365,8 +381,10 @@ class EventType_x_Org(Base):
|
|
365
381
|
org_id: Mapped[int] = mapped_column(ForeignKey("orgs.id"))
|
366
382
|
is_default: Mapped[bool]
|
367
383
|
|
368
|
-
event_type: Mapped["EventType"] = relationship(
|
369
|
-
|
384
|
+
event_type: Mapped["EventType"] = relationship(
|
385
|
+
back_populates="event_type_x_org", lazy="joined"
|
386
|
+
)
|
387
|
+
org: Mapped["Org"] = relationship(back_populates="event_type_x_org", lazy="joined")
|
370
388
|
|
371
389
|
|
372
390
|
class EventTag(Base):
|
@@ -405,8 +423,12 @@ class EventTag_x_Event(Base):
|
|
405
423
|
event_id: Mapped[int] = mapped_column(ForeignKey("events.id"))
|
406
424
|
event_tag_id: Mapped[int] = mapped_column(ForeignKey("event_tags.id"))
|
407
425
|
|
408
|
-
event: Mapped["Event"] = relationship(
|
409
|
-
|
426
|
+
event: Mapped["Event"] = relationship(
|
427
|
+
back_populates="event_tag_x_event", lazy="joined"
|
428
|
+
)
|
429
|
+
event_tag: Mapped["EventTag"] = relationship(
|
430
|
+
back_populates="event_tag_x_event", lazy="joined"
|
431
|
+
)
|
410
432
|
|
411
433
|
|
412
434
|
class EventTag_x_Org(Base):
|
@@ -430,8 +452,10 @@ class EventTag_x_Org(Base):
|
|
430
452
|
org_id: Mapped[int] = mapped_column(ForeignKey("orgs.id"))
|
431
453
|
color_override: Mapped[Optional[str]]
|
432
454
|
|
433
|
-
event_tag: Mapped["EventTag"] = relationship(
|
434
|
-
|
455
|
+
event_tag: Mapped["EventTag"] = relationship(
|
456
|
+
back_populates="event_tag_x_org", lazy="joined"
|
457
|
+
)
|
458
|
+
org: Mapped["Org"] = relationship(back_populates="event_tag_x_org", lazy="joined")
|
435
459
|
|
436
460
|
|
437
461
|
class Org_x_Slack(Base):
|
@@ -453,8 +477,10 @@ class Org_x_Slack(Base):
|
|
453
477
|
org_id: Mapped[int] = mapped_column(ForeignKey("orgs.id"))
|
454
478
|
slack_space_id: Mapped[str] = mapped_column(ForeignKey("slack_spaces.id"))
|
455
479
|
|
456
|
-
slack_space: Mapped["SlackSpace"] = relationship(
|
457
|
-
|
480
|
+
slack_space: Mapped["SlackSpace"] = relationship(
|
481
|
+
back_populates="org_x_slack", lazy="joined"
|
482
|
+
)
|
483
|
+
org: Mapped["Org"] = relationship(back_populates="org_x_slack", lazy="joined")
|
458
484
|
|
459
485
|
|
460
486
|
class Location(Base):
|
@@ -492,7 +518,7 @@ class Location(Base):
|
|
492
518
|
address_country: Mapped[Optional[str]]
|
493
519
|
meta: Mapped[Optional[Dict[str, Any]]]
|
494
520
|
|
495
|
-
org: Mapped["Org"] = relationship(back_populates="locations")
|
521
|
+
org: Mapped["Org"] = relationship(back_populates="locations", lazy="joined")
|
496
522
|
|
497
523
|
|
498
524
|
class Event(Base):
|
@@ -533,6 +559,8 @@ class Event(Base):
|
|
533
559
|
attendance (List[Attendance]): The attendance records for this event.
|
534
560
|
event_tags_x_event (List[EventTag_x_Event]): The event tags associated with this event.
|
535
561
|
event_types_x_event (List[EventType_x_Event]): The event types associated with this event.
|
562
|
+
event_tags (List[EventTag]): The event tags associated with this event.
|
563
|
+
event_types (List[EventType]): The event types associated with this event.
|
536
564
|
"""
|
537
565
|
|
538
566
|
__tablename__ = "events"
|
@@ -563,19 +591,29 @@ class Event(Base):
|
|
563
591
|
backblast_ts: Mapped[Optional[float]]
|
564
592
|
meta: Mapped[Optional[Dict[str, Any]]]
|
565
593
|
|
566
|
-
org: Mapped["Org"] = relationship(back_populates="events")
|
567
|
-
location: Mapped["Location"] = relationship(back_populates="events")
|
594
|
+
org: Mapped["Org"] = relationship(back_populates="events", lazy="joined")
|
595
|
+
location: Mapped["Location"] = relationship(back_populates="events", lazy="joined")
|
568
596
|
series: Mapped["Event"] = relationship(
|
569
|
-
back_populates="events", remote_side="Event.id"
|
597
|
+
back_populates="events", remote_side="Event.id", lazy="joined"
|
598
|
+
)
|
599
|
+
occurences: Mapped[List["Event"]] = relationship(
|
600
|
+
back_populates="series", lazy="joined"
|
601
|
+
)
|
602
|
+
attendance: Mapped[List["Attendance"]] = relationship(
|
603
|
+
back_populates="events", lazy="joined"
|
570
604
|
)
|
571
|
-
occurences: Mapped[List["Event"]] = relationship(back_populates="series")
|
572
|
-
attendance: Mapped[List["Attendance"]] = relationship(back_populates="events")
|
573
605
|
event_tags_x_event: Mapped[List["EventTag_x_Event"]] = relationship(
|
574
606
|
back_populates="events"
|
575
607
|
)
|
576
608
|
event_types_x_event: Mapped[List["EventType_x_Event"]] = relationship(
|
577
609
|
back_populates="events"
|
578
610
|
)
|
611
|
+
event_tags: Mapped[List["EventTag"]] = relationship(
|
612
|
+
back_populates="event", secondary="event_tags_x_event", lazy="joined"
|
613
|
+
)
|
614
|
+
event_types: Mapped[List["EventType"]] = relationship(
|
615
|
+
back_populates="event", secondary="event_types_x_event", lazy="joined"
|
616
|
+
)
|
579
617
|
|
580
618
|
|
581
619
|
class AttendanceType(Base):
|
@@ -621,10 +659,10 @@ class Attendance(Base):
|
|
621
659
|
is_planned: Mapped[bool]
|
622
660
|
meta: Mapped[Optional[Dict[str, Any]]]
|
623
661
|
|
624
|
-
event: Mapped["Event"] = relationship(back_populates="attendance")
|
625
|
-
user: Mapped["User"] = relationship(back_populates="attendance")
|
662
|
+
event: Mapped["Event"] = relationship(back_populates="attendance", lazy="joined")
|
663
|
+
user: Mapped["User"] = relationship(back_populates="attendance", lazy="joined")
|
626
664
|
attendance_type: Mapped["AttendanceType"] = relationship(
|
627
|
-
back_populates="attendance"
|
665
|
+
back_populates="attendance", lazy="joined"
|
628
666
|
)
|
629
667
|
|
630
668
|
|
@@ -647,6 +685,8 @@ class User(Base):
|
|
647
685
|
achievements_x_user (List[Achievement_x_User]): The achievements associated with this user.
|
648
686
|
positions_x_orgs_x_users (List[Position_x_Org_x_User]): The positions associated with this user.
|
649
687
|
roles_x_users_x_org (List[Role_x_User_x_Org]): The roles associated with this user.
|
688
|
+
positions (List[Position]): The positions associated with this user.
|
689
|
+
roles (List[Role]): The roles associated with this user.
|
650
690
|
"""
|
651
691
|
|
652
692
|
__tablename__ = "users"
|
@@ -660,9 +700,13 @@ class User(Base):
|
|
660
700
|
avatar_url: Mapped[Optional[str]]
|
661
701
|
meta: Mapped[Optional[Dict[str, Any]]]
|
662
702
|
|
663
|
-
home_region: Mapped["Org"] = relationship(back_populates="users")
|
664
|
-
attendance: Mapped[List["Attendance"]] = relationship(
|
665
|
-
|
703
|
+
home_region: Mapped["Org"] = relationship(back_populates="users", lazy="joined")
|
704
|
+
attendance: Mapped[List["Attendance"]] = relationship(
|
705
|
+
back_populates="users", lazy="joined"
|
706
|
+
)
|
707
|
+
slack_users: Mapped[List["SlackUser"]] = relationship(
|
708
|
+
back_populates="users", lazy="joined"
|
709
|
+
)
|
666
710
|
achievements_x_user: Mapped[List["Achievement_x_User"]] = relationship(
|
667
711
|
back_populates="user"
|
668
712
|
)
|
@@ -672,6 +716,15 @@ class User(Base):
|
|
672
716
|
roles_x_users_x_org: Mapped[List["Role_x_User_x_Org"]] = relationship(
|
673
717
|
back_populates="user"
|
674
718
|
)
|
719
|
+
achievements: Mapped[List["Achievement"]] = relationship(
|
720
|
+
back_populates="user", secondary="achievements_x_users", lazy="joined"
|
721
|
+
)
|
722
|
+
positions: Mapped[List["Position"]] = relationship(
|
723
|
+
back_populates="user", secondary="positions_x_orgs_x_users", lazy="joined"
|
724
|
+
)
|
725
|
+
roles: Mapped[List["Role"]] = relationship(
|
726
|
+
back_populates="user", secondary="roles_x_users_x_org", lazy="joined"
|
727
|
+
)
|
675
728
|
|
676
729
|
|
677
730
|
class SlackUser(Base):
|
@@ -716,8 +769,10 @@ class SlackUser(Base):
|
|
716
769
|
meta: Mapped[Optional[Dict[str, Any]]]
|
717
770
|
slack_updated: Mapped[Optional[datetime]]
|
718
771
|
|
719
|
-
slack_space: Mapped["SlackSpace"] = relationship(
|
720
|
-
|
772
|
+
slack_space: Mapped["SlackSpace"] = relationship(
|
773
|
+
back_populates="slack_users", lazy="joined"
|
774
|
+
)
|
775
|
+
user: Mapped["User"] = relationship(back_populates="slack_users", lazy="joined")
|
721
776
|
|
722
777
|
|
723
778
|
class Achievement(Base):
|
@@ -761,9 +816,11 @@ class Achievement_x_User(Base):
|
|
761
816
|
date_awarded: Mapped[date]
|
762
817
|
|
763
818
|
achievement: Mapped["Achievement"] = relationship(
|
764
|
-
back_populates="achievement_x_user"
|
819
|
+
back_populates="achievement_x_user", lazy="joined"
|
820
|
+
)
|
821
|
+
user: Mapped["User"] = relationship(
|
822
|
+
back_populates="achievement_x_user", lazy="joined"
|
765
823
|
)
|
766
|
-
user: Mapped["User"] = relationship(back_populates="achievement_x_user")
|
767
824
|
|
768
825
|
|
769
826
|
class Achievement_x_Org(Base):
|
@@ -786,9 +843,9 @@ class Achievement_x_Org(Base):
|
|
786
843
|
org_id: Mapped[int] = mapped_column(ForeignKey("orgs.id"))
|
787
844
|
|
788
845
|
achievement: Mapped["Achievement"] = relationship(
|
789
|
-
back_populates="achievement_x_org"
|
846
|
+
back_populates="achievement_x_org", lazy="joined"
|
790
847
|
)
|
791
|
-
org: Mapped["Org"] = relationship(back_populates="achievement_x_org")
|
848
|
+
org: Mapped["Org"] = relationship(back_populates="achievement_x_org", lazy="joined")
|
792
849
|
|
793
850
|
|
794
851
|
class Position(Base):
|
@@ -798,16 +855,16 @@ class Position(Base):
|
|
798
855
|
Attributes:
|
799
856
|
name (str): The name of the position.
|
800
857
|
description (Optional[str]): A description of the position.
|
801
|
-
org_type_id (int): The ID of the associated organization type.
|
802
|
-
org_id (int): The ID of the associated organization.
|
858
|
+
org_type_id (Optional[int]): The ID of the associated organization type. This is used to limit the positions available to certain types of organizations. If null, the position is available to all organization types.
|
859
|
+
org_id (Optional[int]): The ID of the associated organization. This is used to limit the positions available to certain organizations. If null, the position is available to all organizations.
|
803
860
|
"""
|
804
861
|
|
805
862
|
__tablename__ = "positions"
|
806
863
|
|
807
864
|
name: Mapped[str]
|
808
865
|
description: Mapped[Optional[str]]
|
809
|
-
org_type_id: Mapped[int] = mapped_column(ForeignKey("org_types.id"))
|
810
|
-
org_id: Mapped[int] = mapped_column(ForeignKey("orgs.id"))
|
866
|
+
org_type_id: Mapped[Optional[int]] = mapped_column(ForeignKey("org_types.id"))
|
867
|
+
org_id: Mapped[Optional[int]] = mapped_column(ForeignKey("orgs.id"))
|
811
868
|
|
812
869
|
|
813
870
|
class Position_x_Org_x_User(Base):
|
@@ -834,9 +891,15 @@ class Position_x_Org_x_User(Base):
|
|
834
891
|
org_id: Mapped[int] = mapped_column(ForeignKey("orgs.id"))
|
835
892
|
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
|
836
893
|
|
837
|
-
position: Mapped["Position"] = relationship(
|
838
|
-
|
839
|
-
|
894
|
+
position: Mapped["Position"] = relationship(
|
895
|
+
back_populates="position_x_org_x_user", lazy="joined"
|
896
|
+
)
|
897
|
+
org: Mapped["Org"] = relationship(
|
898
|
+
back_populates="position_x_org_x_user", lazy="joined"
|
899
|
+
)
|
900
|
+
user: Mapped["User"] = relationship(
|
901
|
+
back_populates="position_x_org_x_user", lazy="joined"
|
902
|
+
)
|
840
903
|
|
841
904
|
|
842
905
|
class Expansion(Base):
|
@@ -885,5 +948,9 @@ class Expansion_x_User(Base):
|
|
885
948
|
date: Mapped[date]
|
886
949
|
notes: Mapped[Optional[text]]
|
887
950
|
|
888
|
-
expansion: Mapped["Expansion"] = relationship(
|
889
|
-
|
951
|
+
expansion: Mapped["Expansion"] = relationship(
|
952
|
+
back_populates="expansion_x_user", lazy="joined"
|
953
|
+
)
|
954
|
+
user: Mapped["User"] = relationship(
|
955
|
+
back_populates="expansion_x_user", lazy="joined"
|
956
|
+
)
|
@@ -1,15 +1,15 @@
|
|
1
1
|
import os
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from typing import List, Tuple, TypeVar
|
3
|
+
from typing import List, Optional, Tuple, TypeVar
|
4
4
|
|
5
5
|
import sqlalchemy
|
6
|
-
from sqlalchemy import and_
|
6
|
+
from sqlalchemy import and_, select
|
7
7
|
|
8
8
|
from sqlalchemy.dialects.postgresql import insert
|
9
9
|
from sqlalchemy.engine import Engine
|
10
10
|
from sqlalchemy.orm import sessionmaker
|
11
11
|
|
12
|
-
from .models import Base
|
12
|
+
from f3_data_models.models import Base
|
13
13
|
|
14
14
|
from pydot import Dot
|
15
15
|
from sqlalchemy_schemadisplay import create_schema_graph
|
@@ -88,10 +88,18 @@ class DbManager:
|
|
88
88
|
session.rollback()
|
89
89
|
close_session(session)
|
90
90
|
|
91
|
-
def
|
91
|
+
def get(cls: T, id: int) -> T:
|
92
92
|
session = get_session()
|
93
93
|
try:
|
94
|
-
|
94
|
+
return session.scalars(select(cls).filter(cls.id == id)).one()
|
95
|
+
finally:
|
96
|
+
session.rollback()
|
97
|
+
close_session(session)
|
98
|
+
|
99
|
+
def find_records(cls: T, filters: Optional[List]) -> List[T]:
|
100
|
+
session = get_session()
|
101
|
+
try:
|
102
|
+
records = session.scalars(select(cls).filter(*filters)).all()
|
95
103
|
for r in records:
|
96
104
|
session.expunge(r)
|
97
105
|
return records
|
@@ -99,6 +107,17 @@ class DbManager:
|
|
99
107
|
session.rollback()
|
100
108
|
close_session(session)
|
101
109
|
|
110
|
+
def find_first_record(cls: T, filters: Optional[List]) -> T:
|
111
|
+
session = get_session()
|
112
|
+
try:
|
113
|
+
record = session.scalars(select(cls).filter(*filters)).first()
|
114
|
+
if record:
|
115
|
+
session.expunge(record)
|
116
|
+
return record
|
117
|
+
finally:
|
118
|
+
session.rollback()
|
119
|
+
close_session(session)
|
120
|
+
|
102
121
|
def find_join_records2(left_cls: T, right_cls: T, filters) -> List[Tuple[T]]:
|
103
122
|
session = get_session()
|
104
123
|
try:
|
@@ -247,12 +266,12 @@ def create_diagram():
|
|
247
266
|
graph: Dot = create_schema_graph(
|
248
267
|
engine=get_engine(),
|
249
268
|
metadata=Base.metadata,
|
250
|
-
show_datatypes=
|
251
|
-
show_indexes=
|
269
|
+
show_datatypes=True,
|
270
|
+
show_indexes=True,
|
252
271
|
rankdir="LR",
|
253
|
-
|
272
|
+
show_column_keys=True,
|
254
273
|
)
|
255
|
-
graph.write_png("schema_diagram.png")
|
274
|
+
graph.write_png("docs/_static/schema_diagram.png")
|
256
275
|
|
257
276
|
|
258
277
|
if __name__ == "__main__":
|
File without changes
|
File without changes
|