Opened 7 years ago
Closed 7 years ago
#30172 closed Bug (fixed)
Incorrect migration applying for new Meta.constraints/indexes and field check/unique or unique/index_together constraints with same fields for postgres
| Reported by: | Pavel Tyslacki | Owned by: | Pavel Tyslacki | 
|---|---|---|---|
| Component: | Migrations | Version: | 2.2 | 
| Severity: | Release blocker | Keywords: | |
| Cc: | Triage Stage: | Accepted | |
| Has patch: | yes | Needs documentation: | no | 
| Needs tests: | no | Patch needs improvement: | no | 
| Easy pickings: | no | UI/UX: | no | 
Description
Case 1: trying remove check constraint from field when CheckConstraint exists in Meta.constraints with same field will remove both constraints:
class TestCheck(models.Model):
    f1 = models.PositiveIntegerField()  # will change to `f1 = models.IntegerField()`
    class Meta:
        constraints = [
            models.CheckConstraint(check=models.Q(f1__gte=0), name='TestCheck_f1_check'),
        ]
# initial migration:
        migrations.CreateModel(
            name='TestCheck',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('f1', models.PositiveIntegerField()),
            ],
        ),
        migrations.AddConstraint(
            model_name='testcheck',
            constraint=models.CheckConstraint(check=models.Q(f1__gte=0), name='TestCheck_f1_check'),
        ),
# applied migration:
        migrations.AlterField(
            model_name='testcheck',
            name='f1',
            field=models.IntegerField(),
        ),
Case 2: trying remove unique=True from field when UniqueConstraint exists in Meta.constraints with same field will remove both constraints or raise exception if UniqueConstraint has condition:
class TestUniqCondField(models.Model):
    f1 = models.IntegerField(unique=True)  # will change to `f1 = models.IntegerField()`
    class Meta:
        constraints = [
            models.UniqueConstraint(fields=['f1'], name='TestUniqCondField_f1_uniq', condition=models.Q(f1__gte=0)),
        ]
# initial migration:
        migrations.CreateModel(
            name='TestUniqCondField',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('f1', models.IntegerField(unique=True)),
            ],
        ),
        migrations.AddConstraint(
            model_name='testuniqcondfield',
            constraint=models.UniqueConstraint(condition=models.Q(f1__gte=0), fields=('f1',), name='TestUniqCondField_f1_uniq'),
        ),
# applied migration:
        migrations.AlterField(
            model_name='testuniqcondfield',
            name='f1',
            field=models.IntegerField(),
        ),
Case 3: trying remove Meta.unique_together for same UniqueConstraint.fields in Meta.constraints get incorrect state via introspection (the same if UniqueConstraint has condition):
class TestUniqTogether(models.Model):
    f1 = models.IntegerField()
    f2 = models.IntegerField()
    class Meta:
        unique_together = [
            ('f1', 'f2'),  # will be removed
        ]
        constraints = [
            models.UniqueConstraint(fields=['f1', 'f2'], name='TestUniqTogether_f1_f2_uniq'),
        ]
# initial migration:
        migrations.CreateModel(
            name='TestUniqTogether',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('f1', models.IntegerField()),
                ('f2', models.IntegerField()),
            ],
        ),
        migrations.AddConstraint(
            model_name='testuniqtogether',
            constraint=models.UniqueConstraint(fields=('f1', 'f2'), name='TestUniqTogether_f1_f2_uniq'),
        ),
        migrations.AlterUniqueTogether(
            name='testuniqtogether',
            unique_together={('f1', 'f2')},
        ),
# applied migration
        migrations.AlterUniqueTogether(
            name='testuniqtogether',
            unique_together=set(),
        ),
Case 4: trying remove Meta.index_together for same Index.fields in Meta.indexes get incorrect state via introspection (the same if Index has condition):
class TestIndexTogether(models.Model):
    f1 = models.IntegerField()
    f2 = models.IntegerField()
    class Meta:
        index_together = [
            ('f1', 'f2'),  # will be removed
        ]
        indexes = [
            models.Index(fields=['f1', 'f2'], name='TestIndexTogether_f1_f2_index'),
        ]
# initial migration:
        migrations.CreateModel(
            name='TestIndexTogether',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('f1', models.IntegerField()),
                ('f2', models.IntegerField()),
            ],
        ),
        migrations.AddIndex(
            model_name='testindextogether',
            index=models.Index(fields=['f1', 'f2'], name='TestIndexTogether_f1_f2_index'),
        ),
        migrations.AlterIndexTogether(
            name='testindextogether',
            index_together={('f1', 'f2')},
        ),
# applied migration:
        migrations.AlterIndexTogether(
            name='testindextogether',
            index_together=set(),
        ),
      Change History (11)
comment:1 by , 7 years ago
| Summary: | Incorrect migration applying for new Meta.constraints/indexes and field check/unique or unique/index_together with same fields → Incorrect migration applying for new Meta.constraints/indexes and field check/unique or unique/index_together constraints with same fields for postgres | 
|---|
comment:2 by , 7 years ago
| Has patch: | set | 
|---|---|
| Owner: | changed from to | 
| Status: | new → assigned | 
follow-up: 4 comment:3 by , 7 years ago
| Patch needs improvement: | set | 
|---|---|
| Triage Stage: | Unreviewed → Accepted | 
Can you look into the SQLite failures?
comment:4 by , 7 years ago
comment:5 by , 7 years ago
| Patch needs improvement: | unset | 
|---|
comment:6 by , 7 years ago
| Severity: | Normal → Release blocker | 
|---|
Marking as a release blocker since it's a bug in a new feature (Meta.constraints).
comment:11 by , 7 years ago
| Resolution: | → fixed | 
|---|---|
| Status: | assigned → closed | 
PR