Opened 3 years ago

Closed 3 years ago

#32386 closed Bug (duplicate)

ForeignKey index is removed upon creation of a UniqueConstraint, which breaks migrating backwards

Reported by: Tijmen Owned by: nobody
Component: Migrations Version: 3.1
Severity: Normal Keywords: backward migration unique constraint foreignkey index
Cc: tijmen@… Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When adding a UniqueConstraint on a ForeignKey field combined with another field, the original db index on the ForeignKey is removed and replaced by the unique constraint.
This crashes the migration when trying to migrate backwards, because the foreignkey needs to have an index.

django.db.utils.OperationalError: (1553, "Cannot drop index 'modelb_unique_position': needed in a foreign key constraint")

It makes no difference whether the unique constraint is added in the same or a separate migration.
In the example below it's separated into 2 different migrations.

Expect behavior would be either for the index not be dropped when creating the unique constraint, or for the index to be added before removing the unique constraint when migrating backwards.

First migration:

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

    dependencies = [
        ('appname', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='ModelA',
            fields=[
                ('id', models.AutoField(
                    auto_created=True,
                    primary_key=True,
                    serialize=False,
                    verbose_name='ID')),
            ],
        ),
        migrations.CreateModel(
            name='ModelB',
            fields=[
                ('id', models.AutoField(
                    auto_created=True,
                    primary_key=True,
                    serialize=False,
                    verbose_name='ID')),
                ('a_instance', models.ForeignKey(
                    on_delete=django.db.models.deletion.PROTECT,
                    related_name='bees',
                    to='appname.modela',
                    verbose_name=('modela',))),
                ('position', models.IntegerField(
                    default=0,
                    null=True,
                    verbose_name='volgorde')),
            ],
        ),
    ]

second migration:

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

    dependencies = [
        ('appname', '0002_modela_modelb'),
    ]

    operations = [
        migrations.AddConstraint(
            model_name='modelb',
            constraint=models.UniqueConstraint(
                fields=('a_instance', 'position'),
                name='modelb_unique_position'),
        ),
    ]

Change History (1)

comment:1 by Simon Charette, 3 years ago

Resolution: duplicate
Status: newclosed

I assume you are using MySQL, if it's the case then that's a duplicate of #31335, see https://code.djangoproject.com/ticket/#comment:2.

Note: See TracTickets for help on using tickets.
Back to Top