Opened 23 months ago

Last modified 22 months ago

#34333 closed Bug

Django migrations adds constraint before adding field — at Version 2

Reported by: Raphael Beekmann Owned by: nobody
Component: Migrations Version: 4.1
Severity: Normal Keywords: migration, constraint, field
Cc: Durval Carvalho, David Wobrock Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Raphael Beekmann)

Hello,

I have a model, already created through previous migrations, and in a new migration I added a new field with an UniqueConstraint. The migrations script try to create the constraint first and then the new field, resulting an error :

django.core.exceptions.FieldDoesNotExist: NewModel has no field named 'category'

To reproduce the bug :

  1. Create a project with two models linked together with a One-to-Many relation and an unique constraint :
class Type(models.Model):
    name = models.CharField(max_length=10)


class Model(models.Model):
    name = models.CharField(max_length=10)
    type = models.ForeignKey(Type, on_delete=models.SET_NULL, null=True)
    date = models.DateField(auto_now=True)

    class Meta:
        constraints = (
            models.UniqueConstraint(fields=('date', 'type'), name='unique_type_for_date'),
        )
  1. Create a migration file with manage.py makemigrations
  1. Add a new model with another One-to-Many relation and unique constraint. The models looks like this :
class Type(models.Model):
    name = models.CharField(max_length=10)


class Category(models.Model):
    name = models.CharField(max_length=10)


class Model(models.Model):
    name = models.CharField(max_length=10)
    type = models.ForeignKey(Type, on_delete=models.SET_NULL, null=True)
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
    date = models.DateField(auto_now=True)

    class Meta:
        constraints = (
            models.UniqueConstraint(fields=('date', 'type'), name='unique_type_for_date'),
            models.UniqueConstraint(fields=('date', 'category'), name='unique_category_for_date'),
        )
  1. Create a new migration file. The order of the migration's steps are incorrect and the migration crash :
class Migration(migrations.Migration):

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

    operations = [
        migrations.CreateModel(
            name='Category',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(max_length=10)),
            ],
        ),
        migrations.AddConstraint(
            model_name='model',
            constraint=models.UniqueConstraint(fields=('date', 'category'), name='unique_category_for_date'),
        ),
        migrations.AddField(
            model_name='model',
            name='category',
            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='app.category'),
        ),
    ]

Change History (2)

comment:1 by Mariusz Felisiak, 22 months ago

Resolution: needsinfo
Status: newclosed

Thanks for the report, however I cannot reproduce this issue. For me, makemigrations generates operations in the correct order. Please reopen the ticket if you can debug your issue and provide a small project that reproduces it.

comment:2 by Raphael Beekmann, 22 months ago

Description: modified (diff)
Resolution: needsinfo
Status: closednew
Note: See TracTickets for help on using tickets.
Back to Top