#35078: Incorrect order of migration operations when a new FK is added and is 
part
of constraints as well
-------------------------------------+-------------------------------------
               Reporter:  Arpit      |          Owner:  nobody
  Goel                               |
                   Type:  Bug        |         Status:  new
              Component:             |        Version:  4.2
  Migrations                         |       Keywords:  migration
               Severity:  Normal     |  operations order
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  1
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 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.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/35078>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018cc8f1bb9e-2a04608b-0ae9-4848-9e90-56bb6de28dc9-000000%40eu-central-1.amazonses.com.

Reply via email to