﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
30172	Incorrect migration applying for new Meta.constraints/indexes and field check/unique or unique/index_together constraints with same fields for postgres	Pavel Tyslacki	Pavel Tyslacki	"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(),
        ),
}}}
"	Bug	closed	Migrations	2.2	Release blocker	fixed			Accepted	1	0	0	0	0	0
