@@ -118,20 +118,51 @@ def _get_super_entities_by_ctype(model_objs_by_ctype, model_ids_to_sync, sync_al
118
118
return super_entities_by_ctype
119
119
120
120
121
- def _get_model_objs_to_sync (model_ids_to_sync , model_objs_map , sync_all ):
121
+ def _fetch_entity_models (model_ids_to_sync , model_objs_map , model_objs_by_ctype , sync_all ):
122
+ """
123
+ Fetch the entity models per content type. This will also handle the
124
+ case where accounts are created before _get_super_entities_by_ctype and
125
+ the model_ids_to_sync do not match the model_objs_map
126
+ """
127
+ for ctype , model_ids in model_ids_to_sync .items ():
128
+
129
+ if sync_all :
130
+
131
+ # Build a set of ids of already fetched models
132
+ fetched_model_ids = {
133
+ model .id
134
+ for model in model_objs_by_ctype [ctype ]
135
+ }
136
+
137
+ # Compute the set diff to see if any records are missing
138
+ unfetched_model_ids = model_ids - fetched_model_ids
139
+ else :
140
+ unfetched_model_ids = model_ids
141
+
142
+ # Check if new records
143
+ if unfetched_model_ids :
144
+
145
+ # Fetch the records and add them to the model_objs_map
146
+ model_qset = entity_registry .entity_registry .get (ctype .model_class ()).queryset
147
+ model_objs_to_sync = model_qset .filter (id__in = unfetched_model_ids )
148
+ for model_obj in model_objs_to_sync :
149
+ model_objs_by_ctype [ctype ].append (model_obj )
150
+ model_objs_map [(ctype , model_obj .id )] = model_obj
151
+
152
+
153
+ def _get_model_objs_to_sync (model_ids_to_sync , model_objs_map , model_objs_by_ctype , sync_all ):
122
154
"""
123
155
Given the model IDs to sync, fetch all model objects to sync
124
156
"""
125
157
model_objs_to_sync = {}
126
- for ctype , model_ids_to_sync_for_ctype in model_ids_to_sync .items ():
127
- model_qset = entity_registry .entity_registry .get (ctype .model_class ()).queryset
128
158
129
- if not sync_all :
130
- model_objs_to_sync [ctype ] = model_qset .filter (id__in = model_ids_to_sync_for_ctype )
131
- else :
132
- model_objs_to_sync [ctype ] = [
133
- model_objs_map [ctype , model_id ] for model_id in model_ids_to_sync_for_ctype
134
- ]
159
+ _fetch_entity_models (model_ids_to_sync , model_objs_map , model_objs_by_ctype , sync_all )
160
+
161
+ for ctype , model_ids_to_sync_for_ctype in model_ids_to_sync .items ():
162
+ model_objs_to_sync [ctype ] = [
163
+ model_objs_map [ctype , model_id ]
164
+ for model_id in model_ids_to_sync_for_ctype
165
+ ]
135
166
136
167
return model_objs_to_sync
137
168
@@ -231,32 +262,10 @@ def sync(self):
231
262
# IDs of sub/super entity relationships
232
263
super_entities_by_ctype = _get_super_entities_by_ctype (model_objs_by_ctype , model_ids_to_sync , sync_all )
233
264
234
- # Handle the case where accounts are created before _get_super_entities_by_ctype and
235
- # the model_ids_to_sync do not match the model_objs_map
236
- for ctype , model_ids in model_ids_to_sync .items ():
237
-
238
- # Build a set of ids of already fetched models
239
- ids_of_fetched_models = {
240
- model .id
241
- for model in model_objs_by_ctype [ctype ]
242
- }
243
-
244
- # Compute the set diff to see if any new records were created
245
- created_model_ids = model_ids - ids_of_fetched_models
246
-
247
- # Check if new records
248
- if created_model_ids :
249
-
250
- # Fetch the records and add them to the model_objs_map
251
- new_records = ctype .model_class ().objects .filter (id__in = created_model_ids )
252
- for new_record in new_records :
253
- model_objs_by_ctype [ctype ].append (new_record )
254
- model_objs_map [(ctype , new_record .id )] = new_record
255
-
256
265
# Now that we have all models we need to sync, fetch them so that we can extract
257
266
# metadata and entity kinds. If we are syncing all entities, we've already fetched
258
267
# everything and can fill in this data struct without doing another DB hit
259
- model_objs_to_sync = _get_model_objs_to_sync (model_ids_to_sync , model_objs_map , sync_all )
268
+ model_objs_to_sync = _get_model_objs_to_sync (model_ids_to_sync , model_objs_map , model_objs_by_ctype , sync_all )
260
269
261
270
# Obtain all entity kind tuples associated with the models
262
271
entity_kind_tuples_to_sync = set ()
@@ -384,7 +393,7 @@ def upsert_entity_kinds(self, entity_kinds):
384
393
# Select all our existing entity kinds for update so we can do proper locking
385
394
# We have to select all here for some odd reason, if we only select the ones
386
395
# we are syncing we still run into deadlock issues
387
- list (EntityKind .all_objects .all ().select_for_update ().values_list ('id' , flat = True ))
396
+ list (EntityKind .all_objects .all ().order_by ( 'id' ). select_for_update ().values_list ('id' , flat = True ))
388
397
389
398
# Upsert the entity kinds
390
399
upserted_enitity_kinds = manager_utils .bulk_upsert (
@@ -412,7 +421,7 @@ def upsert_entities(self, entities, sync=False):
412
421
if entities :
413
422
# Default select for update query when syncing all
414
423
select_for_update_query = (
415
- 'SELECT FROM {table_name} FOR NO KEY UPDATE'
424
+ 'SELECT FROM {table_name} ORDER BY id ASC FOR NO KEY UPDATE'
416
425
).format (
417
426
table_name = Entity ._meta .db_table
418
427
)
@@ -421,7 +430,10 @@ def upsert_entities(self, entities, sync=False):
421
430
# If we are not syncing all, only select those we are updating
422
431
if not sync :
423
432
select_for_update_query = (
424
- 'SELECT FROM {table_name} WHERE (entity_type_id, entity_id) IN %s FOR NO KEY UPDATE'
433
+ 'SELECT FROM {table_name} '
434
+ 'WHERE (entity_type_id, entity_id) IN %s '
435
+ 'ORDER BY id ASC '
436
+ 'FOR NO KEY UPDATE'
425
437
).format (
426
438
table_name = Entity ._meta .db_table
427
439
)
@@ -506,7 +518,7 @@ def upsert_entity_relationships(self, queryset, entity_relationships):
506
518
507
519
# Select the relationships for update
508
520
if entity_relationships :
509
- list (queryset .select_for_update ().values_list (
521
+ list (queryset .order_by ( 'id' ). select_for_update ().values_list (
510
522
'id' ,
511
523
flat = True
512
524
))
0 commit comments