provisionning: grab existing roles by uuid in one query (#55043)

This commit is contained in:
Emmanuel Cazenave 2021-06-21 17:49:28 +02:00
parent 438b79dc7e
commit 32ce076834
2 changed files with 14 additions and 3 deletions

View File

@ -130,6 +130,17 @@ class NotificationProcessing:
def provision_role(cls, issuer, action, data, full=False):
logger = logging.getLogger(__name__)
uuids = set()
roles_by_uuid = dict()
if action == 'provision':
# first pass to gather existing roles by uuid
target_uuids = set()
for o in data:
assert 'uuid' in o
target_uuids.add(o['uuid'])
for role in Role.objects.filter(uuid__in=target_uuids):
roles_by_uuid[role.uuid] = role
for o in data:
assert 'uuid' in o
uuids.add(o['uuid'])
@ -137,9 +148,9 @@ class NotificationProcessing:
assert cls.check_valid_role(o)
role_name = cls.truncate_role_name(o['name'])
try:
role = Role.objects.get(uuid=o['uuid'])
role = roles_by_uuid[o['uuid']]
created = False
except Role.DoesNotExist:
except KeyError:
try:
with atomic():
role, created = Role.objects.get_or_create(

View File

@ -243,7 +243,7 @@ def test_hobo_notify_roles_db_queries(caplog, tenants):
}
with CaptureQueriesContext(connection) as ctx:
Command.process_notification(tenant, notification)
assert len(ctx.captured_queries) == 36
assert len(ctx.captured_queries) == 33
assert Group.objects.count() == 2
assert Role.objects.count() == 2