mirror of
				https://github.com/zulip/zulip.git
				synced 2025-11-03 21:43:21 +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"
 | 
						|
            ),
 | 
						|
        ),
 | 
						|
    ]
 |