f3-data-models 0.4.3__py3-none-any.whl → 0.4.4__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.
f3_data_models/models.py CHANGED
@@ -777,13 +777,12 @@ class User(Base):
777
777
  """ # noqa: E501
778
778
 
779
779
  __tablename__ = "users"
780
- __table_args__ = (Index("idx_users_email", func.lower("email"), unique=True),)
781
780
 
782
781
  id: Mapped[intpk]
783
782
  f3_name: Mapped[Optional[str]]
784
783
  first_name: Mapped[Optional[str]]
785
784
  last_name: Mapped[Optional[str]]
786
- email: Mapped[str] = mapped_column(CIText)
785
+ email: Mapped[str] = mapped_column(CIText, unique=True)
787
786
  phone: Mapped[Optional[str]]
788
787
  emergency_contact: Mapped[Optional[str]]
789
788
  emergency_phone: Mapped[Optional[str]]
f3_data_models/testing.py CHANGED
@@ -1,33 +1,12 @@
1
- from f3_data_models.models import Event, Day_Of_Week, Event_Cadence, EventType_x_Event
2
- import datetime
1
+ from f3_data_models.models import User
3
2
  from f3_data_models.utils import DbManager
4
3
 
5
4
 
6
5
  def test_update_event():
7
- event = Event(
8
- org_id=3,
9
- location_id=2,
10
- is_series=True,
11
- is_active=True,
12
- highlight=True,
13
- start_date=datetime.date(2025, 2, 17),
14
- end_date=datetime.date(2026, 2, 17),
15
- start_time="0400",
16
- end_time="0600",
17
- event_x_event_types=[
18
- EventType_x_Event(event_type_id=3),
19
- ],
20
- recurrence_pattern=Event_Cadence.weekly,
21
- day_of_week=Day_Of_Week.monday,
22
- recurrence_interval=1,
23
- index_within_interval=1,
24
- name="Test Event",
6
+ user = User(
7
+ email="evan.Petzoldt@protonmail.com",
25
8
  )
26
- update_dict = event.to_update_dict()
27
- DbManager.update_record(Event, 3, update_dict)
28
-
29
- # event = DbManager.get(Event, 3)
30
- DbManager.delete_records(Event, [Event.series_id == 3])
9
+ DbManager.create_record(user)
31
10
 
32
11
 
33
12
  if __name__ == "__main__":
f3_data_models/utils.py CHANGED
@@ -1,24 +1,21 @@
1
1
  import os
2
2
  from dataclasses import dataclass
3
- from typing import List, Optional, Tuple, TypeVar, Type, Generic # noqa
3
+ from typing import Generic, List, Optional, Tuple, Type, TypeVar # noqa
4
4
 
5
+ import pg8000
5
6
  import sqlalchemy
6
- from sqlalchemy import Select, and_, select, inspect
7
-
7
+ from google.cloud.sql.connector import Connector, IPTypes
8
+ from pydot import Dot
9
+ from sqlalchemy import Select, and_, inspect, select
8
10
  from sqlalchemy.dialects.postgresql import insert
9
11
  from sqlalchemy.engine import Engine
10
- from sqlalchemy.orm import sessionmaker, joinedload
12
+ from sqlalchemy.orm import class_mapper, joinedload, sessionmaker
13
+ from sqlalchemy.orm.attributes import InstrumentedAttribute
11
14
  from sqlalchemy.orm.collections import InstrumentedList
15
+ from sqlalchemy_schemadisplay import create_schema_graph
12
16
 
13
17
  from f3_data_models.models import Base
14
18
 
15
- from pydot import Dot
16
- from sqlalchemy_schemadisplay import create_schema_graph
17
- from google.cloud.sql.connector import Connector, IPTypes
18
- import pg8000
19
- from sqlalchemy.orm import class_mapper
20
- from sqlalchemy.orm.attributes import InstrumentedAttribute
21
-
22
19
 
23
20
  @dataclass
24
21
  class DatabaseField:
@@ -53,9 +50,7 @@ def get_engine(echo=False) -> Engine:
53
50
  )
54
51
  return conn
55
52
 
56
- engine = sqlalchemy.create_engine(
57
- "postgresql+pg8000://", creator=get_connection, echo=echo
58
- )
53
+ engine = sqlalchemy.create_engine("postgresql+pg8000://", creator=get_connection, echo=echo)
59
54
  return engine
60
55
 
61
56
 
@@ -81,10 +76,7 @@ T = TypeVar("T")
81
76
 
82
77
  def _joinedloads(cls: T, query: Select, joinedloads: list | str) -> Select:
83
78
  if joinedloads == "all":
84
- joinedloads = [
85
- getattr(cls, relationship.key)
86
- for relationship in cls.__mapper__.relationships
87
- ]
79
+ joinedloads = [getattr(cls, relationship.key) for relationship in cls.__mapper__.relationships]
88
80
  return query.options(*[joinedload(load) for load in joinedloads])
89
81
 
90
82
 
@@ -101,9 +93,7 @@ class DbManager:
101
93
  session.rollback()
102
94
  close_session(session)
103
95
 
104
- def find_records(
105
- cls: T, filters: Optional[List], joinedloads: List | str = []
106
- ) -> List[T]:
96
+ def find_records(cls: T, filters: Optional[List], joinedloads: List | str = []) -> List[T]:
107
97
  session = get_session()
108
98
  try:
109
99
  query = select(cls)
@@ -117,9 +107,7 @@ class DbManager:
117
107
  session.rollback()
118
108
  close_session(session)
119
109
 
120
- def find_first_record(
121
- cls: T, filters: Optional[List], joinedloads: List | str = []
122
- ) -> T:
110
+ def find_first_record(cls: T, filters: Optional[List], joinedloads: List | str = []) -> T:
123
111
  session = get_session()
124
112
  try:
125
113
  query = select(cls)
@@ -136,21 +124,14 @@ class DbManager:
136
124
  def find_join_records2(left_cls: T, right_cls: T, filters) -> List[Tuple[T]]:
137
125
  session = get_session()
138
126
  try:
139
- records = (
140
- session.query(left_cls, right_cls)
141
- .join(right_cls)
142
- .filter(and_(*filters))
143
- .all()
144
- )
127
+ records = session.query(left_cls, right_cls).join(right_cls).filter(and_(*filters)).all()
145
128
  session.expunge_all()
146
129
  return records
147
130
  finally:
148
131
  session.rollback()
149
132
  close_session(session)
150
133
 
151
- def find_join_records3(
152
- left_cls: T, right_cls1: T, right_cls2: T, filters, left_join=False
153
- ) -> List[Tuple[T]]:
134
+ def find_join_records3(left_cls: T, right_cls1: T, right_cls2: T, filters, left_join=False) -> List[Tuple[T]]:
154
135
  session = get_session()
155
136
  try:
156
137
  records = (
@@ -176,7 +157,7 @@ class DbManager:
176
157
  mapper = class_mapper(cls)
177
158
  relationships = mapper.relationships.keys()
178
159
  for attr, value in fields.items():
179
- key = attr.key
160
+ key = attr if isinstance(attr, str) else attr.key
180
161
  if hasattr(cls, key) and key not in relationships:
181
162
  if isinstance(attr, InstrumentedAttribute):
182
163
  setattr(record, key, value)
@@ -194,24 +175,17 @@ class DbManager:
194
175
  if isinstance(value, list) and og_primary_key:
195
176
  # Delete existing related records
196
177
  related_class = relationship.mapper.class_
197
- related_relationships = class_mapper(
198
- related_class
199
- ).relationships.keys()
200
- session.query(related_class).filter(
201
- getattr(related_class, og_primary_key) == id
202
- ).delete()
178
+ related_relationships = class_mapper(related_class).relationships.keys()
179
+ session.query(related_class).filter(getattr(related_class, og_primary_key) == id).delete()
203
180
  # Add new related records
204
181
  items = [item.__dict__ for item in value]
205
182
  for related_item in items:
206
183
  update_dict = {
207
184
  k: v
208
185
  for k, v in related_item.items()
209
- if hasattr(related_class, k)
210
- and k not in related_relationships
186
+ if hasattr(related_class, k) and k not in related_relationships
211
187
  }
212
- related_record = related_class(
213
- **{og_primary_key: id, **update_dict}
214
- )
188
+ related_record = related_class(**{og_primary_key: id, **update_dict})
215
189
  session.add(related_record)
216
190
 
217
191
  try:
@@ -234,9 +208,7 @@ class DbManager:
234
208
  # Update simple fields
235
209
  for attr, value in fields.items():
236
210
  key = attr.key
237
- if key in valid_attributes and not isinstance(
238
- value, InstrumentedList
239
- ):
211
+ if key in valid_attributes and not isinstance(value, InstrumentedList):
240
212
  setattr(obj, key, value)
241
213
 
242
214
  # Update relationships separately
@@ -256,9 +228,7 @@ class DbManager:
256
228
  if isinstance(value, list) and og_primary_key:
257
229
  # Delete existing related records
258
230
  related_class = relationship.mapper.class_
259
- related_relationships = class_mapper(
260
- related_class
261
- ).relationships.keys()
231
+ related_relationships = class_mapper(related_class).relationships.keys()
262
232
  session.query(related_class).filter(
263
233
  getattr(related_class, og_primary_key) == obj.id
264
234
  ).delete()
@@ -268,12 +238,9 @@ class DbManager:
268
238
  update_dict = {
269
239
  k: v
270
240
  for k, v in related_item.items()
271
- if hasattr(related_class, k)
272
- and k not in related_relationships
241
+ if hasattr(related_class, k) and k not in related_relationships
273
242
  }
274
- related_record = related_class(
275
- **{og_primary_key: obj.id, **update_dict}
276
- )
243
+ related_record = related_class(**{og_primary_key: obj.id, **update_dict})
277
244
  session.add(related_record)
278
245
 
279
246
  session.flush()
@@ -307,11 +274,7 @@ class DbManager:
307
274
  session = get_session()
308
275
  try:
309
276
  for record in records:
310
- record_dict = {
311
- k: v
312
- for k, v in record.__dict__.items()
313
- if k != "_sa_instance_state"
314
- }
277
+ record_dict = {k: v for k, v in record.__dict__.items() if k != "_sa_instance_state"}
315
278
  stmt = insert(cls).values(record_dict).on_conflict_do_nothing()
316
279
  session.execute(stmt)
317
280
  session.flush()
@@ -323,15 +286,9 @@ class DbManager:
323
286
  session = get_session()
324
287
  try:
325
288
  for record in records:
326
- record_dict = {
327
- k: v
328
- for k, v in record.__dict__.items()
329
- if k != "_sa_instance_state"
330
- }
289
+ record_dict = {k: v for k, v in record.__dict__.items() if k != "_sa_instance_state"}
331
290
  stmt = insert(cls).values(record_dict)
332
- update_dict = {
333
- c.name: getattr(record, c.name) for c in cls.__table__.columns
334
- }
291
+ update_dict = {c.name: getattr(record, c.name) for c in cls.__table__.columns}
335
292
  stmt = stmt.on_conflict_do_update(
336
293
  index_elements=[cls.__table__.primary_key.columns.keys()],
337
294
  set_=update_dict,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: f3-data-models
3
- Version: 0.4.3
3
+ Version: 0.4.4
4
4
  Summary: The data schema and models for F3 Nation applications.
5
5
  License: MIT
6
6
  Author: Evan Petzoldt
@@ -0,0 +1,7 @@
1
+ f3_data_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ f3_data_models/models.py,sha256=q_oQEe2Ccvcnl5l4Zf4fYNoogiT_1SSa8vMNmbW_QH8,45973
3
+ f3_data_models/testing.py,sha256=fdiwiSy0ZoYbsXAKhukVHMJr7WvBLwD20Tg949wshmk,265
4
+ f3_data_models/utils.py,sha256=l9x2nEcIrnjDLkIAATDsZ5I-0Y2sg1u_sfkBcRKrTu4,13051
5
+ f3_data_models-0.4.4.dist-info/METADATA,sha256=fTfrpyeuWFQKRRM79NlpO4U2j6CVboBmBKD8sxCYOv8,2766
6
+ f3_data_models-0.4.4.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
7
+ f3_data_models-0.4.4.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.1.1
2
+ Generator: poetry-core 2.1.2
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,7 +0,0 @@
1
- f3_data_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- f3_data_models/models.py,sha256=3bJUsEC-lENYt5ezqN0pbUQTV3znndLnWnrJVQ3vJOk,46043
3
- f3_data_models/testing.py,sha256=KmTjMe345-NZCdHNaNnOyL33J8D5oVdqdIhYIKbM8XM,968
4
- f3_data_models/utils.py,sha256=UpNx1E_kmt8_1vN4fdFSy55yPCoDA2algzof_5EAJ2k,13835
5
- f3_data_models-0.4.3.dist-info/METADATA,sha256=5_8Rauj6G4fOY5QGaXtgl0nsdUfATnUGBPLISPPCJ_Y,2766
6
- f3_data_models-0.4.3.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
7
- f3_data_models-0.4.3.dist-info/RECORD,,