Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit e304277

Browse files
authored
Merge pull request #160 from somewes/develop
fix queries
2 parents acc8ce7 + 25bd6ac commit e304277

File tree

4 files changed

+60
-38
lines changed

4 files changed

+60
-38
lines changed

entity/sync.py

+41-32
Original file line numberDiff line numberDiff line change
@@ -118,20 +118,51 @@ def _get_super_entities_by_ctype(model_objs_by_ctype, model_ids_to_sync, sync_al
118118
return super_entities_by_ctype
119119

120120

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):
122154
"""
123155
Given the model IDs to sync, fetch all model objects to sync
124156
"""
125157
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
128158

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+
]
135166

136167
return model_objs_to_sync
137168

@@ -231,32 +262,10 @@ def sync(self):
231262
# IDs of sub/super entity relationships
232263
super_entities_by_ctype = _get_super_entities_by_ctype(model_objs_by_ctype, model_ids_to_sync, sync_all)
233264

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-
256265
# Now that we have all models we need to sync, fetch them so that we can extract
257266
# metadata and entity kinds. If we are syncing all entities, we've already fetched
258267
# 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)
260269

261270
# Obtain all entity kind tuples associated with the models
262271
entity_kind_tuples_to_sync = set()

entity/tests/sync_tests.py

+16-5
Original file line numberDiff line numberDiff line change
@@ -309,23 +309,34 @@ def test_sync_all_accounts_teams_deleted_account_during_sync(self):
309309
accounts[3].save()
310310

311311
def wrapped_super_entities(*args, **kwargs):
312-
if Account.objects.filter(email='[email protected]').exists():
313-
Account.objects.filter(email='[email protected]').delete()
312+
account = Account.objects.filter(email='[email protected]', is_active=True).first()
313+
if account:
314+
account.is_active = False
315+
account.save()
314316

315317
return _get_super_entities_by_ctype(*args, **kwargs)
316318

317-
# Sync all the entities. There should be 6 (4 accounts 2 teams)
319+
# Sync the accounts
318320
with patch('entity.sync._get_super_entities_by_ctype', wraps=wrapped_super_entities):
319321
sync_entities(*accounts)
320-
# Sync again to hit other wrapped function branch and make sure it doesn't error
322+
account = Account.objects.get(email='[email protected]')
323+
entity = Entity.all_objects.get_for_obj(account)
324+
self.assertEqual(entity.is_active, False)
325+
326+
# Fetch accounts and sync again - hits other block in wrapped function
327+
with patch('entity.sync._get_super_entities_by_ctype', wraps=wrapped_super_entities):
328+
accounts = Account.objects.all()
321329
sync_entities(*accounts)
330+
account = Account.objects.get(email='[email protected]')
331+
entity = Entity.all_objects.get_for_obj(account)
332+
self.assertEqual(entity.is_active, False)
322333

323334
self.assertEquals(Entity.objects.filter(entity_type=ContentType.objects.get_for_model(Account)).count(), 4)
324335
self.assertEquals(Entity.objects.filter(entity_type=ContentType.objects.get_for_model(Team)).count(), 2)
325336
self.assertEquals(Entity.objects.all().count(), 6)
326337

327338
# There should be six entity relationships
328-
self.assertEquals(EntityRelationship.objects.all().count(), 3)
339+
self.assertEquals(EntityRelationship.objects.all().count(), 4)
329340

330341
def test_sync_all_accounts_teams_inactive_entity_kind(self):
331342
"""

entity/version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '5.0.1'
1+
__version__ = '5.0.2'

release_notes.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## Release Notes
22

3+
- 5.0.2:
4+
- Only fetch new entities on a sync_all
35
- 5.0.1:
46
- Fix bug where an entity created or deleted during a sync would cause errors
57
- 5.0.0:

0 commit comments

Comments
 (0)