mirror of
https://github.com/zulip/zulip.git
synced 2025-10-24 08:33:43 +00:00
Migrate all `ids` of anything which does not have a foreign key from the Message or UserMessage table (and would thus require walking those) to be `bigint`. This is done by removing explicit `BigAutoField`s, trading them for explicit `AutoField`s on the tables to not be migrated, while updating `DEFAULT_AUTO_FIELD` to the new default. In general, the tables adjusted in this commit are small tables -- at least compared to Messages and UserMessages. Many-to-many tables without their own model class are adjusted by a custom Operation, since they do not automatically pick up migrations when `DEFAULT_AUTO_FIELD` changes[^1]. Note that this does multiple scans over tables to update foreign keys[^2]. Large installs may wish to hand-optimize this using the output of `./manage.py sqlmigrate` to join multiple `ALTER TABLE` statements into one, to speed up the migration. This is unfortunately not possible to do generically, as constraint names may differ between installations. This leaves the following primary keys as non-`bigint`: - `auth_group.id` - `auth_group_permissions.id` - `auth_permission.id` - `django_content_type.id` - `django_migrations.id` - `otp_static_staticdevice.id` - `otp_static_statictoken.id` - `otp_totp_totpdevice.id` - `two_factor_phonedevice.id` - `zerver_archivedmessage.id` - `zerver_client.id` - `zerver_message.id` - `zerver_realm.id` - `zerver_recipient.id` - `zerver_userprofile.id` [^1]: https://code.djangoproject.com/ticket/32674 [^2]: https://code.djangoproject.com/ticket/24203
392 lines
14 KiB
Python
392 lines
14 KiB
Python
from typing import Any
|
|
|
|
from django.db import migrations, models
|
|
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
|
|
from django.db.migrations.operations.base import Operation
|
|
from typing_extensions import override
|
|
|
|
|
|
class MigrateIdToBigint(Operation):
|
|
"""A helper to migrate the id of a given table to bigint.
|
|
|
|
Necessary for many-to-many intermediate tables without models, due
|
|
to https://code.djangoproject.com/ticket/32674"""
|
|
|
|
def __init__(self, model_name: str) -> None:
|
|
self.model_name = model_name
|
|
|
|
@override
|
|
def state_forwards(self, app_label: str, state: Any) -> None:
|
|
pass
|
|
|
|
@override
|
|
def database_forwards(
|
|
self,
|
|
app_label: str,
|
|
schema_editor: BaseDatabaseSchemaEditor,
|
|
from_state: Any,
|
|
to_state: Any,
|
|
) -> None:
|
|
model = from_state.apps.get_model(app_label, self.model_name)
|
|
table_name = model._meta.db_table
|
|
seq_name = table_name + "_id_seq"
|
|
schema_editor.execute(
|
|
f"ALTER TABLE {schema_editor.quote_name(table_name)} ALTER COLUMN id SET DATA TYPE bigint"
|
|
)
|
|
schema_editor.execute(f"ALTER SEQUENCE {schema_editor.quote_name(seq_name)} AS bigint")
|
|
|
|
@override
|
|
def database_backwards(
|
|
self,
|
|
app_label: str,
|
|
schema_editor: BaseDatabaseSchemaEditor,
|
|
from_state: Any,
|
|
to_state: Any,
|
|
) -> None:
|
|
model = from_state.apps.get_model(app_label, self.model_name)
|
|
table_name = model._meta.db_table
|
|
seq_name = table_name + "_id_seq"
|
|
schema_editor.execute(
|
|
f"ALTER TABLE {schema_editor.quote_name(table_name)} ALTER COLUMN id SET DATA TYPE int"
|
|
)
|
|
schema_editor.execute(f"ALTER SEQUENCE {schema_editor.quote_name(seq_name)} AS int")
|
|
|
|
@override
|
|
def describe(self) -> str:
|
|
return f"Migrates the 'id' column of {self.model_name} and its sequence to be a bigint. Requires that the table have no foreign keys."
|
|
|
|
|
|
class Migration(migrations.Migration):
|
|
atomic = False
|
|
|
|
dependencies = [
|
|
("zerver", "0530_alter_useractivity_id_alter_useractivityinterval_id"),
|
|
]
|
|
|
|
operations = [
|
|
MigrateIdToBigint("archivedattachment_messages"),
|
|
MigrateIdToBigint("attachment_messages"),
|
|
MigrateIdToBigint("attachment_scheduled_messages"),
|
|
MigrateIdToBigint("defaultstreamgroup_streams"),
|
|
MigrateIdToBigint("multiuseinvite_streams"),
|
|
MigrateIdToBigint("preregistrationuser_streams"),
|
|
MigrateIdToBigint("scheduledemail_users"),
|
|
MigrateIdToBigint("userprofile_groups"),
|
|
MigrateIdToBigint("userprofile_user_permissions"),
|
|
migrations.AlterField(
|
|
model_name="alertword",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="archivedattachment",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="archivedreaction",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="archivedsubmessage",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="archivetransaction",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="attachment",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="botconfigdata",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="botstoragedata",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="customprofilefield",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="customprofilefieldvalue",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="defaultstream",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="defaultstreamgroup",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="draft",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="emailchangestatus",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="groupgroupmembership",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="huddle",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="missedmessageemailaddress",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="multiuseinvite",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="muteduser",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="onboardingstep",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="preregistrationrealm",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="preregistrationuser",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="presencesequence",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="pushdevicetoken",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="reaction",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="realmauditlog",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="realmauthenticationmethod",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="realmdomain",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="realmemoji",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="realmfilter",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="realmplayground",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="realmreactivationstatus",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="realmuserdefault",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="scheduledemail",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="scheduledmessage",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="scheduledmessagenotificationemail",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="service",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="stream",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="submessage",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="subscription",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="usergroup",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="usergroupmembership",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="userpresence",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="userstatus",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
migrations.AlterField(
|
|
model_name="usertopic",
|
|
name="id",
|
|
field=models.BigAutoField(
|
|
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
|
|
),
|
|
),
|
|
]
|