2
2
from __future__ import annotations
3
3
4
4
import datetime
5
- from typing import Any , Callable , Iterable
5
+ from typing import Any , Callable , Iterable , Literal
6
6
7
7
import sqlalchemy
8
8
from sqlalchemy import Table
@@ -109,15 +109,21 @@ def get_unique_constraints(table: Table, context: Context) -> list[list[str]]:
109
109
return list_of_constraints
110
110
111
111
112
- def table_dict_save (table_dict : dict [str , Any ],
113
- ModelClass : Any ,
114
- context : Context ,
115
- extra_attrs : Iterable [str ] = ()) -> Any :
112
+ def table_dict_save (
113
+ table_dict : dict [str , Any ],
114
+ ModelClass : Any ,
115
+ context : Context ,
116
+ extra_attrs : Iterable [str ] = ()
117
+ ) -> tuple [Any , Literal ['create' , 'update' , None ]]:
116
118
'''Given a dict and a model class, update or create a sqlalchemy object.
117
119
This will use an existing object if "id" is supplied OR if any unique
118
120
constraints are met. e.g supplying just a tag name will get out that tag
119
121
obj.
120
122
123
+ Returns (obj, change) where change is:
124
+ - 'create' if this is a new object
125
+ - 'update' if any fields were changed or extra_attrs passed
126
+ - None if no change for an existing object
121
127
'''
122
128
session = context ["session" ]
123
129
@@ -130,7 +136,8 @@ def table_dict_save(table_dict: dict[str, Any],
130
136
if id :
131
137
obj = session .get (ModelClass , id )
132
138
133
- if not obj and isinstance (table , Table ):
139
+ new = not obj
140
+ if new :
134
141
unique_constraints = get_unique_constraints (table , context )
135
142
for constraint in unique_constraints :
136
143
params = dict ((key , table_dict .get (key )) for key in constraint )
@@ -146,11 +153,13 @@ def table_dict_save(table_dict: dict[str, Any],
146
153
if not obj :
147
154
obj = ModelClass ()
148
155
149
- obj .from_dict (table_dict )
156
+ changed , _skipped = obj .from_dict (table_dict )
150
157
for a in extra_attrs :
151
158
if a in table_dict :
152
159
setattr (obj , a , table_dict [a ])
153
160
154
161
session .add (obj )
155
162
156
- return obj
163
+ return (
164
+ obj , 'create' if new else 'update' if changed or extra_attrs else None
165
+ )
0 commit comments