f3-data-models 0.5.3__py3-none-any.whl → 0.5.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/utils.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import os
|
2
|
+
from contextlib import contextmanager
|
2
3
|
from dataclasses import dataclass
|
3
4
|
from typing import Generic, List, Optional, Tuple, Type, TypeVar # noqa
|
4
5
|
|
@@ -53,48 +54,52 @@ def get_engine(echo=False) -> Engine:
|
|
53
54
|
return engine
|
54
55
|
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
return GLOBAL_SESSION
|
57
|
+
GLOBAL_ENGINE = get_engine(echo=os.environ.get("SQL_ECHO", "False") == "True")
|
58
|
+
GLOBAL_SESSION = sessionmaker(bind=GLOBAL_ENGINE)
|
59
59
|
|
60
|
-
global GLOBAL_ENGINE
|
61
|
-
GLOBAL_ENGINE = get_engine(echo=echo)
|
62
|
-
return sessionmaker()(bind=GLOBAL_ENGINE)
|
63
60
|
|
61
|
+
def get_session():
|
62
|
+
return GLOBAL_SESSION()
|
64
63
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
64
|
+
|
65
|
+
@contextmanager
|
66
|
+
def session_scope():
|
67
|
+
"""Provide a transactional scope around a series of operations."""
|
68
|
+
session = get_session()
|
69
|
+
try:
|
70
|
+
yield session
|
71
|
+
session.commit()
|
72
|
+
except Exception as e:
|
73
|
+
session.rollback()
|
74
|
+
raise e
|
75
|
+
finally:
|
76
|
+
session.close()
|
71
77
|
|
72
78
|
|
73
79
|
T = TypeVar("T")
|
74
80
|
|
75
81
|
|
76
|
-
def _joinedloads(cls: T, query: Select, joinedloads: list | str) -> Select:
|
82
|
+
def _joinedloads(cls: T, query: Select, joinedloads: list | str = None) -> Select:
|
83
|
+
if joinedloads is None:
|
84
|
+
return query
|
77
85
|
if joinedloads == "all":
|
78
86
|
joinedloads = [getattr(cls, relationship.key) for relationship in cls.__mapper__.relationships]
|
79
87
|
return query.options(*[joinedload(load) for load in joinedloads])
|
80
88
|
|
81
89
|
|
82
90
|
class DbManager:
|
83
|
-
|
84
|
-
|
85
|
-
|
91
|
+
@classmethod
|
92
|
+
def get(cls: Type[T], id: int, joinedloads: list | str = None) -> T:
|
93
|
+
with session_scope() as session:
|
86
94
|
query = select(cls).filter(cls.id == id)
|
87
95
|
query = _joinedloads(cls, query, joinedloads)
|
88
96
|
record = session.scalars(query).unique().one()
|
89
97
|
session.expunge(record)
|
90
98
|
return record
|
91
|
-
finally:
|
92
|
-
session.rollback()
|
93
|
-
close_session(session)
|
94
99
|
|
95
|
-
|
96
|
-
|
97
|
-
|
100
|
+
@classmethod
|
101
|
+
def find_records(cls: T, filters: Optional[List], joinedloads: List | str = None) -> List[T]:
|
102
|
+
with session_scope() as session:
|
98
103
|
query = select(cls)
|
99
104
|
query = _joinedloads(cls, query, joinedloads)
|
100
105
|
query = query.filter(*filters)
|
@@ -102,13 +107,10 @@ class DbManager:
|
|
102
107
|
for r in records:
|
103
108
|
session.expunge(r)
|
104
109
|
return records
|
105
|
-
finally:
|
106
|
-
session.rollback()
|
107
|
-
close_session(session)
|
108
110
|
|
109
|
-
|
110
|
-
|
111
|
-
|
111
|
+
@classmethod
|
112
|
+
def find_first_record(cls: T, filters: Optional[List], joinedloads: List | str = None) -> T:
|
113
|
+
with session_scope() as session:
|
112
114
|
query = select(cls)
|
113
115
|
query = _joinedloads(cls, query, joinedloads)
|
114
116
|
query = query.filter(*filters)
|
@@ -116,40 +118,33 @@ class DbManager:
|
|
116
118
|
if record:
|
117
119
|
session.expunge(record)
|
118
120
|
return record
|
119
|
-
finally:
|
120
|
-
session.rollback()
|
121
|
-
close_session(session)
|
122
121
|
|
122
|
+
@classmethod
|
123
123
|
def find_join_records2(left_cls: T, right_cls: T, filters) -> List[Tuple[T]]:
|
124
|
-
|
125
|
-
|
126
|
-
records =
|
124
|
+
with session_scope() as session:
|
125
|
+
result = session.execute(select(left_cls, right_cls).join(right_cls).filter(and_(*filters)))
|
126
|
+
records = result.all()
|
127
127
|
session.expunge_all()
|
128
128
|
return records
|
129
|
-
finally:
|
130
|
-
session.rollback()
|
131
|
-
close_session(session)
|
132
129
|
|
130
|
+
@classmethod
|
133
131
|
def find_join_records3(left_cls: T, right_cls1: T, right_cls2: T, filters, left_join=False) -> List[Tuple[T]]:
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
session.query(left_cls, right_cls1, right_cls2)
|
132
|
+
with session_scope() as session:
|
133
|
+
result = session.execute(
|
134
|
+
select(left_cls, right_cls1, right_cls2)
|
138
135
|
.select_from(left_cls)
|
139
136
|
.join(right_cls1, isouter=left_join)
|
140
137
|
.join(right_cls2, isouter=left_join)
|
141
138
|
.filter(and_(*filters))
|
142
|
-
.all()
|
143
139
|
)
|
140
|
+
records = result.all()
|
144
141
|
session.expunge_all()
|
145
142
|
return records
|
146
|
-
finally:
|
147
|
-
session.rollback()
|
148
|
-
close_session(session)
|
149
143
|
|
144
|
+
@classmethod
|
150
145
|
def update_record(cls: T, id, fields):
|
151
|
-
with
|
152
|
-
record = session.
|
146
|
+
with session_scope() as session:
|
147
|
+
record = session.get(cls, id)
|
153
148
|
if not record:
|
154
149
|
raise ValueError(f"Record with id {id} not found in {cls.__name__}")
|
155
150
|
|
@@ -160,10 +155,6 @@ class DbManager:
|
|
160
155
|
print(f"key: {key}, value: {value}")
|
161
156
|
if hasattr(cls, key) and key not in relationships:
|
162
157
|
setattr(record, key, value)
|
163
|
-
# if isinstance(attr, InstrumentedAttribute):
|
164
|
-
# setattr(record, key, value)
|
165
|
-
# else:
|
166
|
-
# setattr(record, key, value)
|
167
158
|
elif key in relationships:
|
168
159
|
# Handle relationships separately
|
169
160
|
relationship = mapper.relationships[key]
|
@@ -191,18 +182,10 @@ class DbManager:
|
|
191
182
|
related_record = related_class(**{og_primary_key: id, **update_dict})
|
192
183
|
session.add(related_record)
|
193
184
|
|
194
|
-
|
195
|
-
print(record)
|
196
|
-
session.commit()
|
197
|
-
except pg8000.IntegrityError as e:
|
198
|
-
session.rollback()
|
199
|
-
raise e
|
200
|
-
|
185
|
+
@classmethod
|
201
186
|
def update_records(cls, filters, fields):
|
202
|
-
|
203
|
-
|
204
|
-
# Fetch the objects to be updated
|
205
|
-
objects = session.query(cls).filter(and_(*filters)).all()
|
187
|
+
with session_scope() as session:
|
188
|
+
objects = session.scalars(select(cls).filter(and_(*filters))).all()
|
206
189
|
|
207
190
|
# Get the list of valid attributes for the class
|
208
191
|
valid_attributes = {attr.key for attr in inspect(cls).mapper.column_attrs}
|
@@ -248,47 +231,35 @@ class DbManager:
|
|
248
231
|
session.add(related_record)
|
249
232
|
|
250
233
|
session.flush()
|
251
|
-
finally:
|
252
|
-
session.commit()
|
253
|
-
close_session(session)
|
254
234
|
|
235
|
+
@classmethod
|
255
236
|
def create_record(record: Base) -> Base:
|
256
|
-
|
257
|
-
try:
|
237
|
+
with session_scope() as session:
|
258
238
|
session.add(record)
|
259
239
|
session.flush()
|
260
240
|
session.expunge(record)
|
261
|
-
finally:
|
262
|
-
session.commit()
|
263
|
-
close_session(session)
|
264
241
|
return record # noqa
|
265
242
|
|
243
|
+
@classmethod
|
266
244
|
def create_records(records: List[Base]):
|
267
|
-
|
268
|
-
try:
|
245
|
+
with session_scope() as session:
|
269
246
|
session.add_all(records)
|
270
247
|
session.flush()
|
271
248
|
session.expunge_all()
|
272
|
-
finally:
|
273
|
-
session.commit()
|
274
|
-
close_session(session)
|
275
249
|
return records # noqa
|
276
250
|
|
251
|
+
@classmethod
|
277
252
|
def create_or_ignore(cls: T, records: List[Base]):
|
278
|
-
|
279
|
-
try:
|
253
|
+
with session_scope() as session:
|
280
254
|
for record in records:
|
281
255
|
record_dict = {k: v for k, v in record.__dict__.items() if k != "_sa_instance_state"}
|
282
256
|
stmt = insert(cls).values(record_dict).on_conflict_do_nothing()
|
283
257
|
session.execute(stmt)
|
284
258
|
session.flush()
|
285
|
-
finally:
|
286
|
-
session.commit()
|
287
|
-
close_session(session)
|
288
259
|
|
260
|
+
@classmethod
|
289
261
|
def upsert_records(cls, records):
|
290
|
-
|
291
|
-
try:
|
262
|
+
with session_scope() as session:
|
292
263
|
for record in records:
|
293
264
|
record_dict = {k: v for k, v in record.__dict__.items() if k != "_sa_instance_state"}
|
294
265
|
stmt = insert(cls).values(record_dict)
|
@@ -299,41 +270,29 @@ class DbManager:
|
|
299
270
|
)
|
300
271
|
session.execute(stmt)
|
301
272
|
session.flush()
|
302
|
-
finally:
|
303
|
-
session.commit()
|
304
|
-
close_session(session)
|
305
273
|
|
274
|
+
@classmethod
|
306
275
|
def delete_record(cls: T, id):
|
307
|
-
|
308
|
-
try:
|
276
|
+
with session_scope() as session:
|
309
277
|
session.query(cls).filter(cls.id == id).delete()
|
310
278
|
session.flush()
|
311
|
-
finally:
|
312
|
-
session.commit()
|
313
|
-
close_session(session)
|
314
279
|
|
315
|
-
|
316
|
-
|
317
|
-
|
280
|
+
@classmethod
|
281
|
+
def delete_records(cls: T, filters, joinedloads: List | str = None):
|
282
|
+
with session_scope() as session:
|
318
283
|
query = select(cls)
|
319
284
|
query = _joinedloads(cls, query, joinedloads)
|
320
285
|
query = query.filter(*filters)
|
321
286
|
records = session.scalars(query).unique().all()
|
322
287
|
for r in records:
|
323
288
|
session.delete(r)
|
324
|
-
# session.query(cls).filter(and_(*filters)).delete()
|
325
289
|
session.flush()
|
326
|
-
finally:
|
327
|
-
session.commit()
|
328
|
-
close_session(session)
|
329
290
|
|
291
|
+
@classmethod
|
330
292
|
def execute_sql_query(sql_query):
|
331
|
-
|
332
|
-
try:
|
293
|
+
with session_scope() as session:
|
333
294
|
records = session.execute(sql_query)
|
334
295
|
return records
|
335
|
-
finally:
|
336
|
-
close_session(session)
|
337
296
|
|
338
297
|
|
339
298
|
def create_diagram():
|
@@ -0,0 +1,7 @@
|
|
1
|
+
f3_data_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
f3_data_models/models.py,sha256=omQrhckvosTCiYA4uxsx0Wu7hAm69c4MzIVyGq7iWSQ,51523
|
3
|
+
f3_data_models/testing.py,sha256=UE88nhMrlflrPqeBM8uHcqCAc_p43q_jsSrPep8f01c,654
|
4
|
+
f3_data_models/utils.py,sha256=IL1JBYitZGWFwn_oWPjM-vOwBcuN2muAk5O4ETyMl_0,12069
|
5
|
+
f3_data_models-0.5.4.dist-info/METADATA,sha256=dcyTBJRtGTac4fl7lzx273a7nECbsx53N-SoVR7Uk6w,2766
|
6
|
+
f3_data_models-0.5.4.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
7
|
+
f3_data_models-0.5.4.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
1
|
-
f3_data_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
f3_data_models/models.py,sha256=omQrhckvosTCiYA4uxsx0Wu7hAm69c4MzIVyGq7iWSQ,51523
|
3
|
-
f3_data_models/testing.py,sha256=UE88nhMrlflrPqeBM8uHcqCAc_p43q_jsSrPep8f01c,654
|
4
|
-
f3_data_models/utils.py,sha256=xFhMU6imwWGdH2KdqcAsddILR7FuAftDwfn9tIcLiwM,13208
|
5
|
-
f3_data_models-0.5.3.dist-info/METADATA,sha256=0SrlZ9WS42o15zpRFfN7Km5t6VOxVPkq9u3wfP6o7fc,2766
|
6
|
-
f3_data_models-0.5.3.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
7
|
-
f3_data_models-0.5.3.dist-info/RECORD,,
|
File without changes
|