Opened 17 hours ago

Last modified 17 hours ago

#36598 new Bug

Django migrations is unable to find remove constraints from non-public schema for Postgres

Reported by: Salaah Amin Owned by:
Component: Database layer (models, ORM) Version: 4.2
Severity: Normal Keywords: postgres, db, orm
Cc: Salaah Amin Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I have a table in another schema (analytics) which is created and managed by Django. The following is a snippet of the table:

class Meta:
        db_table = '"analytics"."occupancy"'
        indexes = [models.Index(fields=("business_id", "-dt"))]
        constraints = [
            models.CheckConstraint(
                check=models.Q(occupancy_tables__gte=0.0)
                & models.Q(occupancy_tables___lte=1.0),
                name="occupancy_tables_between_0_and_1",
            ),
            models.CheckConstraint(
                check=models.Q(occupancy_covers__gte=0.0)
                & models.Q(occupancy_covers__lte=1.0),
                name="occupancy_covers_between_0_and_1",
            ),
        ]

If i create a new migration that results in these constraints being removed, it breaks.

Here is the traceback:

Traceback (most recent call last):
  File "..../manage.py", line 25, in <module>
    main()
  File "..../manage.py", line 21, in main
    execute_from_command_line(sys.argv)
  File "....django/core/management/__init__.py", line 442, in execute_from_command_line
    utility.execute()
  File "....django/core/management/__init__.py", line 436, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "....django/core/management/base.py", line 412, in run_from_argv
    self.execute(*args, **cmd_options)
  File "....django/core/management/base.py", line 458, in execute
    output = self.handle(*args, **options)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "....django/core/management/base.py", line 106, in wrapper
    res = handle_func(*args, **kwargs)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "....django/core/management/commands/migrate.py", line 356, in handle
    post_migrate_state = executor.migrate(
                         ^^^^^^^^^^^^^^^^^
  File "....django/db/migrations/executor.py", line 135, in migrate
    state = self._migrate_all_forwards(
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "....django/db/migrations/executor.py", line 167, in _migrate_all_forwards
    state = self.apply_migration(
            ^^^^^^^^^^^^^^^^^^^^^
  File "....django/db/migrations/executor.py", line 252, in apply_migration
    state = migration.apply(state, schema_editor)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "....django/db/migrations/migration.py", line 132, in apply
    operation.database_forwards(
  File "....django/db/migrations/operations/models.py", line 659, in database_forwards
    alter_together(
  File "....django/db/backends/base/schema.py", line 554, in alter_unique_together
    self._delete_composed_index(
  File "....django/db/backends/base/schema.py", line 611, in _delete_composed_index
    raise ValueError(
ValueError: Found wrong number (0) of constraints for "analytics"."occupancy"(business_id, dt)

Taking a look at the code, the problem seems to be caused by `django.lib.backends.postgresql.introspection.DatabaseIntrospection.get_constraints.

The query adds "pg_catalog.pg_table_is_visible(cl.oid)". When I ran that query in pgadmin, removing that condition, the missing constraints appeared.

Looking at the postgres docs, pg_table_is_visible searches the search_path. However, I have added the schema to the search path in the db setup in settings.py:

DATABASES = {
    ...
    "OPTIONS": {
            "options": "-c search_path=public,analytics",
     },
}

Not sure if this is a misconfiguration on my part (couldn't find anything in Django docs), or if this is a bug/missing feature.
I am able to migrate ok when creating new tables, just deleting constraints seem to be a problem.

Note: I am currently using Django version 4.2. But looking at the source code, this (potential) issue may also be in v5.2.

Change History (1)

comment:1 by Salaah Amin, 17 hours ago

Type: UncategorizedBug
Note: See TracTickets for help on using tickets.
Back to Top