diff --git a/zerver/migrations/0455_set_default_for_can_mention_group.py b/zerver/migrations/0455_set_default_for_can_mention_group.py index 86f5ea9f60..c6c6460142 100644 --- a/zerver/migrations/0455_set_default_for_can_mention_group.py +++ b/zerver/migrations/0455_set_default_for_can_mention_group.py @@ -1,36 +1,51 @@ # Generated by Django 4.2.1 on 2023-06-12 10:47 -from django.db import migrations +from django.db import migrations, transaction from django.db.backends.base.schema import BaseDatabaseSchemaEditor from django.db.migrations.state import StateApps +from django.db.models import Max, Min, OuterRef def set_default_value_for_can_mention_group( apps: StateApps, schema_editor: BaseDatabaseSchemaEditor ) -> None: - Realm = apps.get_model("zerver", "Realm") UserGroup = apps.get_model("zerver", "UserGroup") - groups_to_update = [] - for realm in Realm.objects.all(): - # The default value of `can_mention_group` is everyone group for - # all groups except role-based system groups. For role-based system - # groups, we set the value of `can_mention_group` to nobody group. - nobody_group = UserGroup.objects.get(name="@role:nobody", realm=realm, is_system_group=True) - everyone_group = UserGroup.objects.get( - name="@role:everyone", realm=realm, is_system_group=True - ) - for group in UserGroup.objects.filter(realm=realm): - if group.is_system_group: - group.can_mention_group = nobody_group - else: - group.can_mention_group = everyone_group - groups_to_update.append(group) + BATCH_SIZE = 1000 + max_id = UserGroup.objects.filter(can_mention_group=None).aggregate(Max("id"))["id__max"] - UserGroup.objects.bulk_update(groups_to_update, ["can_mention_group"]) + if max_id is None: + # Do nothing if there are no UserGroups on the server. + return + + lower_bound = UserGroup.objects.filter(can_mention_group=None).aggregate(Min("id"))["id__min"] + while lower_bound <= max_id: + upper_bound = lower_bound + BATCH_SIZE - 1 + print(f"Processing batch {lower_bound} to {upper_bound} for UserGroup") + + with transaction.atomic(): + UserGroup.objects.filter( + id__range=(lower_bound, upper_bound), can_mention_group=None, is_system_group=True + ).update( + can_mention_group=UserGroup.objects.filter( + name="@role:nobody", realm=OuterRef("realm"), is_system_group=True + ).values("pk") + ) + + UserGroup.objects.filter( + id__range=(lower_bound, upper_bound), can_mention_group=None, is_system_group=False + ).update( + can_mention_group=UserGroup.objects.filter( + name="@role:everyone", realm=OuterRef("realm"), is_system_group=True + ).values("pk") + ) + + lower_bound += BATCH_SIZE class Migration(migrations.Migration): + atomic = False + dependencies = [ ("zerver", "0454_usergroup_can_mention_group"), ]