Opened 6 years ago
Last modified 6 years ago
#30090 closed Bug
Cannot reverse MySQL DB migration when model has unique_together and one of the fields has db_index=True — at Version 1
Reported by: | Andy McCurdy | Owned by: | nobody |
---|---|---|---|
Component: | Migrations | Version: | 2.1 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
I'm seeing errors attempting to rollback a migration when a model field that has db_index=True
is also included within a unique_together
constraint. From my testing this only happens when the field with the db_index=True
attribute is included in the unique_together
constraint after another field that does not have db_index
specified. In the example below, reversing the order of the fields in the unique_together
allows the migration to rollback without issue.
I have only tested this on MySQL. Other backends may or may not be affected as well.
The following models.py
and 0001_initial.py
files demonstrate the error. I'm using Django 2.1.5 and mysqlclient 1.3.14.
from django.db import models class TestModel(models.Model): field_a = models.IntegerField(db_index=True) field_b = models.IntegerField() class Meta: unique_together = ( ('field_b', 'field_a'), )
This produces the following migration:
# Generated by Django 2.1.5 on 2019-01-10 00:11 from django.db import migrations, models class Migration(migrations.Migration): initial = True dependencies = [ ] operations = [ migrations.CreateModel( name='TestModel', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('field_a', models.IntegerField(db_index=True)), ('field_b', models.IntegerField()), ], ), migrations.AlterUniqueTogether( name='testmodel', unique_together={('field_b', 'field_a')}, ), ]
The migration is applied cleanly. When rolling it back I get this error:
Operations to perform: Unapply all migrations: mysql_error Running migrations: Rendering model states... DONE Unapplying mysql_error.0001_initial...Traceback (most recent call last): File "./manage.py", line 15, in <module> execute_from_command_line(sys.argv) File "/Users/andy/.pyenv/versions/django-test/lib/python3.7/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line utility.execute() File "/Users/andy/.pyenv/versions/django-test/lib/python3.7/site-packages/django/core/management/__init__.py", line 375, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "/Users/andy/.pyenv/versions/django-test/lib/python3.7/site-packages/django/core/management/base.py", line 316, in run_from_argv self.execute(*args, **cmd_options) File "/Users/andy/.pyenv/versions/django-test/lib/python3.7/site-packages/django/core/management/base.py", line 353, in execute output = self.handle(*args, **options) File "/Users/andy/.pyenv/versions/django-test/lib/python3.7/site-packages/django/core/management/base.py", line 83, in wrapped res = handle_func(*args, **kwargs) File "/Users/andy/.pyenv/versions/django-test/lib/python3.7/site-packages/django/core/management/commands/migrate.py", line 203, in handle fake_initial=fake_initial, File "/Users/andy/.pyenv/versions/django-test/lib/python3.7/site-packages/django/db/migrations/executor.py", line 121, in migrate state = self._migrate_all_backwards(plan, full_plan, fake=fake) File "/Users/andy/.pyenv/versions/django-test/lib/python3.7/site-packages/django/db/migrations/executor.py", line 196, in _migrate_all_backwards self.unapply_migration(states[migration], migration, fake=fake) File "/Users/andy/.pyenv/versions/django-test/lib/python3.7/site-packages/django/db/migrations/executor.py", line 262, in unapply_migration state = migration.unapply(state, schema_editor) File "/Users/andy/.pyenv/versions/django-test/lib/python3.7/site-packages/django/db/migrations/migration.py", line 175, in unapply operation.database_backwards(self.app_label, schema_editor, from_state, to_state) File "/Users/andy/.pyenv/versions/django-test/lib/python3.7/site-packages/django/db/migrations/operations/models.py", line 518, in database_backwards return self.database_forwards(app_label, schema_editor, from_state, to_state) File "/Users/andy/.pyenv/versions/django-test/lib/python3.7/site-packages/django/db/migrations/operations/models.py", line 514, in database_forwards getattr(new_model._meta, self.option_name, set()), File "/Users/andy/.pyenv/versions/django-test/lib/python3.7/site-packages/django/db/backends/base/schema.py", line 356, in alter_unique_together self._delete_composed_index(model, fields, {'unique': True}, self.sql_delete_unique) File "/Users/andy/.pyenv/versions/django-test/lib/python3.7/site-packages/django/db/backends/mysql/schema.py", line 82, in _delete_composed_index return super()._delete_composed_index(model, fields, *args) File "/Users/andy/.pyenv/versions/django-test/lib/python3.7/site-packages/django/db/backends/base/schema.py", line 385, in _delete_composed_index ", ".join(columns), ValueError: Found wrong number (0) of constraints for mysql_error_testmodel(field_b, field_a)