performance: Simplify bulk_create_users().

We were going back to the database to get all
the users in the realm, when we had them right
there already.  I believe this is a legacy
of us running on a very old version of Django
(back in early days), where `bulk_create`
didn't give you back ids in a nice way.

In the interim we added the `RealmAuditLog`
code, which does take advantage of the
existing profiles (and proves we can rely
on them).

But meanwhile we were still
doing a query to get all N users in the
realm.  With `selected_related`!

To be fair, bulk_create_users() is by
its very nature a pretty infrequent
operation.  This change is more motivated
by code cleanup.

Now we just loop through user_ids for
the Recipient/Subscriber foreign key rows.

I also removed some fairly convoluted code mapping
emails to user_ids and just work in user_id
space.
This commit is contained in:
Steve Howell 2020-03-06 13:48:49 +00:00 committed by Tim Abbott
parent 1306239c16
commit ecbbc3e365
1 changed files with 12 additions and 15 deletions

View File

@ -35,35 +35,32 @@ def bulk_create_users(realm: Realm,
enter_sends=True)
profiles_to_create.append(profile)
UserProfile.objects.bulk_create(profiles_to_create)
user_ids = {user.id for user in profiles_to_create}
RealmAuditLog.objects.bulk_create(
[RealmAuditLog(realm=realm, modified_user=profile_,
event_type=RealmAuditLog.USER_CREATED, event_time=profile_.date_joined)
for profile_ in profiles_to_create])
profiles_by_email = {} # type: Dict[str, UserProfile]
profiles_by_id = {} # type: Dict[int, UserProfile]
for profile in UserProfile.objects.select_related().filter(realm=realm):
profiles_by_email[profile.email] = profile
profiles_by_id[profile.id] = profile
recipients_to_create = [] # type: List[Recipient]
for (email, full_name, short_name, active) in users:
recipients_to_create.append(Recipient(type_id=profiles_by_email[email].id,
type=Recipient.PERSONAL))
for user_id in user_ids:
recipient = Recipient(type_id=user_id, type=Recipient.PERSONAL)
recipients_to_create.append(recipient)
Recipient.objects.bulk_create(recipients_to_create)
bulk_set_users_or_streams_recipient_fields(UserProfile, profiles_to_create, recipients_to_create)
recipients_by_email = {} # type: Dict[str, Recipient]
recipients_by_user_id = {} # type: Dict[int, Recipient]
for recipient in recipients_to_create:
recipients_by_email[profiles_by_id[recipient.type_id].email] = recipient
recipients_by_user_id[recipient.type_id] = recipient
subscriptions_to_create = [] # type: List[Subscription]
for (email, full_name, short_name, active) in users:
subscriptions_to_create.append(
Subscription(user_profile_id=profiles_by_email[email].id,
recipient=recipients_by_email[email]))
for user_id in user_ids:
recipient = recipients_by_user_id[user_id]
subscription = Subscription(user_profile_id=user_id, recipient=recipient)
subscriptions_to_create.append(subscription)
Subscription.objects.bulk_create(subscriptions_to_create)
def bulk_set_users_or_streams_recipient_fields(model: Model,