migrations: Use bulk_create in migration 0093.

This fixes a performance issue that caused this migration to run for a
really long time.

It still takes about 1 minute to run with the 75K Subscription objects
we have on chat.zulip.org, but that's within the realm of acceptable.
This commit is contained in:
Tim Abbott 2017-07-18 11:36:18 -07:00
parent a36cf3b492
commit 9e81fc39e0
1 changed files with 25 additions and 14 deletions

View File

@ -8,34 +8,45 @@ from django.db import migrations, models
from django.utils.timezone import now as timezone_now from django.utils.timezone import now as timezone_now
from typing import List
def backfill_subscription_log_events(apps, schema_editor): def backfill_subscription_log_events(apps, schema_editor):
# type: (StateApps, DatabaseSchemaEditor) -> None # type: (StateApps, DatabaseSchemaEditor) -> None
migration_time = timezone_now() migration_time = timezone_now()
RealmAuditLog = apps.get_model('zerver', 'RealmAuditLog') RealmAuditLog = apps.get_model('zerver', 'RealmAuditLog')
Subscription = apps.get_model('zerver', 'Subscription') Subscription = apps.get_model('zerver', 'Subscription')
Message = apps.get_model('zerver', 'Message') Message = apps.get_model('zerver', 'Message')
objects_to_create = [] # type: List[RealmAuditLog]
subs_query = Subscription.objects.select_related( subs_query = Subscription.objects.select_related(
"user_profile", "user_profile__realm", "recipient").filter(recipient__type=2) "user_profile", "user_profile__realm", "recipient").filter(recipient__type=2)
for sub in subs_query: for sub in subs_query:
RealmAuditLog.objects.create(realm=sub.user_profile.realm, entry = RealmAuditLog(
modified_user=sub.user_profile, realm=sub.user_profile.realm,
modified_stream_id=sub.recipient.type_id, modified_user=sub.user_profile,
event_last_message_id=0, modified_stream_id=sub.recipient.type_id,
event_type='subscription_created', event_last_message_id=0,
event_time=migration_time, event_type='subscription_created',
backfilled=True) event_time=migration_time,
backfilled=True)
objects_to_create.append(entry)
RealmAuditLog.objects.bulk_create(objects_to_create)
objects_to_create = []
event_last_message_id = Message.objects.aggregate(Max('id'))['id__max'] event_last_message_id = Message.objects.aggregate(Max('id'))['id__max']
migration_time_for_deactivation = timezone_now() migration_time_for_deactivation = timezone_now()
for sub in subs_query.filter(active=False): for sub in subs_query.filter(active=False):
RealmAuditLog.objects.create(realm=sub.user_profile.realm, entry = RealmAuditLog(
modified_user=sub.user_profile, realm=sub.user_profile.realm,
modified_stream_id=sub.recipient.type_id, modified_user=sub.user_profile,
event_last_message_id=event_last_message_id, modified_stream_id=sub.recipient.type_id,
event_type='subscription_deactivated', event_last_message_id=event_last_message_id,
event_time=migration_time_for_deactivation, event_type='subscription_deactivated',
backfilled=True) event_time=migration_time_for_deactivation,
backfilled=True)
objects_to_create.append(entry)
RealmAuditLog.objects.bulk_create(objects_to_create)
objects_to_create = []
def reverse_code(apps, schema_editor): def reverse_code(apps, schema_editor):
# type: (StateApps, DatabaseSchemaEditor) -> None # type: (StateApps, DatabaseSchemaEditor) -> None