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.