#26624 closed Bug (wontfix)
Error when running sqlmigrate after dropping index (of index_together) without actually migrating
| Reported by: | Akshesh Doshi | Owned by: | <default> |
|---|---|---|---|
| Component: | Migrations | Version: | dev |
| Severity: | Normal | Keywords: | sqlmigrate db-indexes |
| Cc: | Jacob Walls | Triage Stage: | Accepted |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description (last modified by )
I get an error when I run sqlmigrate for a migration which drops an index_together constraint until actually migrating the previous migration. It happens for postgres and not for sqlite.
Steps to reproduce the bug:
1) Create app with the following models:
from django.db import models class Brand(models.Model): name = models.CharField(max_length=100, db_index=True) value = models.IntegerField(blank=True, null=True, default=0) class Meta: index_together = ( ('name', 'value'), )
Run python manage.py makemigrations.
Then see the sql statements using python manage.py sqlmigrate <app_name> 0001_initial.
Everything works fine.
2) Remove the index_together part (and the whole Meta class).
Now run python manage.py makemigrations.
Then see the sql statements using python manage.py sqlmigrate <app_name> <migration_name> and an error is thrown.
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "d:\git\django\django\core\management\__init__.py", line 367, in execute_from_command_line
utility.execute()
File "d:\git\django\django\core\management\__init__.py", line 359, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "d:\git\django\django\core\management\base.py", line 305, in run_from_argv
self.execute(*args, **cmd_options)
File "d:\git\django\django\core\management\commands\sqlmigrate.py", line 33, in execute
return super(Command, self).execute(*args, **options)
File "d:\git\django\django\core\management\base.py", line 356, in execute
output = self.handle(*args, **options)
File "d:\git\django\django\core\management\commands\sqlmigrate.py", line 62, in handle
sql_statements = executor.collect_sql(plan)
File "d:\git\django\django\db\migrations\executor.py", line 177, in collect_sql
state = migration.apply(state, schema_editor, collect_sql=True)
File "d:\git\django\django\db\migrations\migration.py", line 129, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "d:\git\django\django\db\migrations\operations\models.py", line 557, in database_forwards
getattr(new_model._meta, self.option_name, set()),
File "d:\git\django\django\db\backends\base\schema.py", line 345, in alter_index_together
self._delete_composed_index(model, fields, {'index': True}, self.sql_delete_index)
File "d:\git\django\django\db\backends\base\schema.py", line 358, in _delete_composed_index
", ".join(columns),
ValueError: Found wrong number (0) of constraints for ert_brand(name, value)
But the problem gets rectified if we migrate the first migration (i.e. 0001_initial in this case).
Change History (9)
comment:1 by , 10 years ago
| Description: | modified (diff) |
|---|
comment:2 by , 9 years ago
| Keywords: | db-indexes added; index removed |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
comment:5 by , 9 months ago
| Cc: | added |
|---|
comment:6 by , 7 months ago
| Resolution: | → wontfix |
|---|---|
| Status: | new → closed |
comment:7 by , 6 months ago
index_together is discouraged, but I don't see anywhere that it's been deprecated, and it will exist in migrations indefinitely. (EDIT: I meant unique_together, see comment:8)
Where I'm seeing this issue is migrating from a model like this
class Meta:
unique_together = (("a", "b", "c"))
to a UniqueConstraint removing one field:
class Meta:
constraints = [
models.UniqueConstraint(
fields=("a", "b"), name="bug_report"
),
]
Then migrate, then sqlmigrate produces ValueError: Found wrong number (0) of constraints, which is not the same as the original report (failure is after migrate, not before)
If the unique constraint is a straight port (not removing any fields):
class Meta:
constraints = [
models.UniqueConstraint(
fields=("a", "b", "c"), name="bug_report"
),
]
... sqlmigrate no longer crashes after migrate, but does not produce the correct SQL:
BEGIN;
--
-- Alter unique_together for cardxnodexwidget (0 constraint(s))
--
ALTER TABLE "table" DROP CONSTRAINT "bug_report"; -- should not say "bug_report"
--
-- Create constraint jtw on model cardxnodexwidget
--
ALTER TABLE "table" ADD CONSTRAINT "bug_report" UNIQUE ("a", "b", "c");
comment:8 by , 6 months ago
index_together is discouraged, but I don't see anywhere that it's been deprecated, and it will exist in migrations indefinitely.
My bad, index_together is definitely deprecated, whereas unique_together is merely discouraged. I confused them because I came here from a duplicate for unique_together: #31834. comment:7 also deals with unique_together.
I think we ought to undo the wontfix. Not sure whether to retitle this ticket for unique_together or start a new one.
comment:9 by , 6 months ago
The first part of my report is all but identical to #31834, so I think it would be simplest to just reopen that ticket and leave this one wontfix'ed. I'll do that now.
Traceback is for PostgreSQL. Seems to work on SQLite, but not on MySQL.