Postgres failure when trying to remove check constraint

72 views
Skip to first unread message

Alan Evangelista

unread,
Oct 4, 2024, 9:51:19 AM10/4/24
to Django users
Hi, everyone.

I have the following db model:

class Template(models.Model):
    max_documents = models.PositiveIntegerField(default=1)
    is_comparison = models.BooleanField(default=False)
    ...
    class Meta:
        constraints = [
            models.CheckConstraint(
                check=models.Q(is_comparison=False) | models.Q(max_documents__gte=2, is_comparison=True),
                name="is_comparison_requires_min_documents",
            ),
        ]

I recently added this check constraint above and makemigrations created the following db migration: 

class Migration(migrations.Migration):
    dependencies = [
        ...
    ]

    operations = [
        migrations.AddConstraint(
            model_name="template",
            constraint=models.CheckConstraint(
                check=models.Q(
                    ("is_comparison", False),
                    models.Q(("is_comparison", True), ("max_documents__gte", 2)),
                    _connector="OR",
                ),
                name="is_comparison_requires_min_documents",
            ),
        ),
    ]

Today I deleted the constraint and ran makemigrations again, which created this second migration:

class Migration(migrations.Migration):
    dependencies = [
        ...
    ]

    operations = [
        migrations.RemoveConstraint(
            model_name="template",
            name="is_comparison_requires_min_documents",
        ),
    ]

When I try to run the 2nd migration, I get the following Postgres error from Django:
django.db.utils.ProgrammingError: constraint "is_comparison_requires_min_documents" of relation "ai_template" does not exist

I checked the ai_template table schema and confirmed there is no check constraint there. It seems to me Django didn't create the check constraint on the Postgres db side (maybe it was enforcing it on its side) and now is trying to remove it from Postgres. Is that a bug or am I missing something?

Thanks in advance!

Alan Evangelista

unread,
Oct 5, 2024, 10:03:37 AM10/5/24
to django...@googlegroups.com
I found out the cause was that I recently removed the max_documents field in the Template model, Postgres automatically deletes a constraint when one of the related columns is deleted and Django does not realize it. I manually updated the Django migration that deleted the field to also deleted the constrain and it worked fine.

--
You received this message because you are subscribed to a topic in the Google Groups "Django users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-users/VBkLU6AP9b4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/8d16410d-ded2-4f2f-a457-675127825443n%40googlegroups.com.

Sam Brown

unread,
Oct 5, 2024, 10:31:23 AM10/5/24
to django...@googlegroups.com
For this exact reason I always use `sqlmigrate` to get the auto generated sql statement (and the backwards sql) and put this statements in  `forwards` and `backwards` functions. I then separate the db and state operations. 

I bet if you run `python manage.py sqlmigrate <app name> <migration>` on the migrations that removes the field from the model, you will see the sql that deletes the index. 

You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAKz%2BTUsu1BE9EzvUxPHfz8ND%2BWL3uA%2B0ZyM9jsWfG%2BektwUt_Q%40mail.gmail.com.
Reply all
Reply to author
Forward
0 new messages