mirror of
https://github.com/zulip/zulip.git
synced 2025-11-02 13:03:29 +00:00
The Django ORM query would not work correctly for pathological DirectMessageGroups with no Subscription rows. When the Subquery gave empty results, the UPDATE would set group_size to null - when the point of the migration was exactly to make sure this column is always set and allow making the column non-nullable in 0575. Such DirectMessageGroups can occur as a result doing .delete() on all UserProfiles that were in the group - or by doing realm deletion via either .delete() or `manage.py delete_realm`. The natural choice for group_size of these objects is 0. The simple SQL query naturally achieves this result, without needing any special handling for this case.
80 lines
2.5 KiB
Python
80 lines
2.5 KiB
Python
# Generated by Django 5.0.6 on 2024-08-16 06:44
|
|
|
|
from django.db import connection, migrations
|
|
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
|
|
from django.db.migrations.state import StateApps
|
|
|
|
BATCH_SIZE = 1000
|
|
|
|
|
|
def backfill_group_size_field_for_direct_message_groups(
|
|
apps: StateApps, schema_editor: BaseDatabaseSchemaEditor
|
|
) -> None:
|
|
Recipient = apps.get_model("zerver", "Recipient")
|
|
|
|
RECIPIENT_DIRECT_MESSAGE_GROUP = 3
|
|
|
|
direct_message_group_recipient_entries = Recipient.objects.filter(
|
|
type=RECIPIENT_DIRECT_MESSAGE_GROUP
|
|
)
|
|
|
|
if not direct_message_group_recipient_entries.exists():
|
|
return
|
|
|
|
recipient_id_lower_bound = direct_message_group_recipient_entries.earliest("id").id
|
|
max_recipient_id = Recipient.objects.latest("id").id
|
|
|
|
# We would like to set the upper bound significantly past the
|
|
# maximum recipient id, because it is likely that new Direct
|
|
# Message Groups are created during this transaction, and their
|
|
# recipient id is assigned as the one right after the max id.
|
|
max_recipient_id += BATCH_SIZE
|
|
|
|
while recipient_id_lower_bound <= max_recipient_id:
|
|
do_backfill_group_size_field_for_direct_message_groups(
|
|
recipient_id_lower_bound,
|
|
min(recipient_id_lower_bound + BATCH_SIZE, max_recipient_id),
|
|
)
|
|
recipient_id_lower_bound += BATCH_SIZE + 1
|
|
|
|
|
|
def do_backfill_group_size_field_for_direct_message_groups(
|
|
recipient_id_lower_bound: int,
|
|
recipient_id_upper_bound: int,
|
|
) -> None:
|
|
with connection.cursor() as cursor:
|
|
update_query = """
|
|
UPDATE zerver_huddle
|
|
SET group_size = (
|
|
SELECT COUNT(*)
|
|
FROM zerver_subscription
|
|
WHERE zerver_subscription.recipient_id = zerver_huddle.recipient_id
|
|
)
|
|
WHERE zerver_huddle.recipient_id BETWEEN %(lower_bound)s AND %(upper_bound)s
|
|
AND zerver_huddle.group_size IS NULL
|
|
"""
|
|
|
|
cursor.execute(
|
|
update_query,
|
|
{
|
|
"lower_bound": recipient_id_lower_bound,
|
|
"upper_bound": recipient_id_upper_bound,
|
|
},
|
|
)
|
|
|
|
|
|
class Migration(migrations.Migration):
|
|
atomic = False
|
|
|
|
dependencies = [
|
|
("zerver", "0573_directmessagegroup_group_size"),
|
|
]
|
|
|
|
operations = [
|
|
migrations.RunPython(
|
|
backfill_group_size_field_for_direct_message_groups,
|
|
elidable=True,
|
|
reverse_code=migrations.RunPython.noop,
|
|
),
|
|
]
|