#35078 closed Bug (duplicate)

Incorrect order of migration operations when a new FK is added and is part of constraints as well

Reported by: Arpit Goel Owned by: nobody
Component: Migrations Version: 4.2
Severity: Normal Keywords: migration operations order
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I had an existing model, say:

class A(models.Model):
    title = models.CharField(max_length=255)
    fk1 = models.ForeignKey(
        User, on_delete=models.CASCADE,
    )

I created a new model B and added an FK in model A such that either fk1 or fk2 must exist.

class B(models.Model):
    title = models.CharField(max_length=255)

class A(models.Model):
    title = models.CharField(max_length=255)
    fk1 = models.ForeignKey(
        User, on_delete=models.SET_NULL, null=True, blank=True
    )
    fk2 = models.ForeignKey(
        B, on_delete=models.SET_NULL, null=True, blank=True
    )
    class Meta:
        constraints = [CheckConstraint(check=Q(fk1__isnull=False) | Q(fk2__isnull=False), name="null_check")]

When I run the makemigrations command, I get the following migration:

class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='B',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('title', models.CharField(max_length=255)),
            ],
        ),
        migrations.AlterField(
            model_name='a',
            name='fk1',
            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
        ),
        
        migrations.AddConstraint(
            model_name='a',
            constraint=models.CheckConstraint(check=models.Q(('fk1__isnull', False), ('fk2__isnull', False), _connector='OR'), name='null_check'),
        ),
        migrations.AddField(
            model_name='a',
            name='fk2',
            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='b'),
        ),
    ]

Ideally, the AddField operation should be done before AddConstraint, or the operation would fail due to a non-existing field. This should be an easy fix I guess, just need to move constraint ops to the end of the list instead of FK being at the end.
For now, I'm fixing the migration manually to make it work.

Change History (1)

comment:1 by Mariusz Felisiak, 12 months ago

Easy pickings: unset
Resolution: duplicate
Status: newclosed

Duplicate of #34333, fixed in 4b1bfea2846f66f504265cec46ee1fe94ee9c98b (Django 5.0+).

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