#24757 closed Bug (fixed)
Removing unique_together constraint make Django 1.8 migration fail with MySQL
| Reported by: | Thomas Recouvreux | Owned by: | Tim Graham |
|---|---|---|---|
| Component: | Migrations | Version: | 1.8 |
| Severity: | Release blocker | Keywords: | migrations mysql |
| Cc: | Triage Stage: | Ready for checkin | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Migrations containing migrations.AlterUniqueTogether(name='xxx', unique_together=set([]),) may fail on Django 1.8 but not on Django 1.7 if using the backend mysql.
Given the database engine is mysql and the following models.py:
from django.db import models
class MyModelA(models.Model):
s = models.CharField(max_length=120)
class MyModelB(models.Model):
a = models.ForeignKey(MyModelA)
b = models.IntegerField()
And the 2 following migrations:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
]
operations = [
migrations.CreateModel(
name='MyModelA',
fields=[
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
('s', models.CharField(max_length=120)),
],
),
migrations.CreateModel(
name='MyModelB',
fields=[
('id', models.AutoField(serialize=False, auto_created=True, verbose_name='ID', primary_key=True)),
('b', models.IntegerField()),
('a', models.ForeignKey(to='mysite.MyModelA')),
],
),
migrations.AlterUniqueTogether(
name='mymodelb',
unique_together=set([('a', 'b')]),
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
class Migration(migrations.Migration):
dependencies = [
('mysite', '0001_initial'),
]
operations = [
migrations.AlterUniqueTogether(
name='mymodelb',
unique_together=set([]),
),
]
Running ./manage.py migrate works fine on Django 1.7, but on Django 1.8 I get the following error:
$ ./manage.py migrate
Operations to perform:
Synchronize unmigrated apps: staticfiles, messages
Apply all migrations: contenttypes, auth, mysite, sessions, admin
Synchronizing apps without migrations:
Creating tables...
Running deferred SQL...
Installing custom SQL...
Running migrations:
Rendering model states... DONE
[..]
Applying mysite.0001_initial... OK
Applying mysite.0002_auto...Traceback (most recent call last):
[..]
django.db.utils.OperationalError: (1553, "Cannot drop index 'mysite_mymodelb_a_id_b53c781c93aab9a_uniq': needed in a foreign key constraint")
The same migrations work on psql, I did not have the chance to test it against sqlite.
Inspecting the generated sql I found Django 1.7 add an index in addition to the unique constraint and Django 1.8 does not.
On Django 1.7
BEGIN; CREATE TABLE `mysite_mymodela` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `s` varchar(120) NOT NULL); CREATE TABLE `mysite_mymodelb` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `b` integer NOT NULL, `a_id` integer NOT NULL); ALTER TABLE `mysite_mymodelb` ADD CONSTRAINT `mysite_mymodelb_a_id_48275010b87402ed_uniq` UNIQUE (`a_id`, `b`); ALTER TABLE `mysite_mymodelb` ADD CONSTRAINT `mysite_mymodelb_a_id_4981d3920f0fef1e_fk_mysite_mymodela_id` FOREIGN KEY (`a_id`) REFERENCES `mysite_mymodela` (`id`); CREATE INDEX `mysite_mymodelb_e2b453f4` ON `mysite_mymodelb` (`a_id`); COMMIT;
Note the CREATE INDEX `mysite_mymodelb_e2b453f4` ON `mysite_mymodelb` (`a_id`);.
And on Django 1.8
BEGIN; CREATE TABLE `mysite_mymodela` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `s` varchar(120) NOT NULL); CREATE TABLE `mysite_mymodelb` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `b` integer NOT NULL, `a_id` integer NOT NULL); ALTER TABLE `mysite_mymodelb` ADD CONSTRAINT `mysite_mymodelb_a_id_784bb266d0e363ab_uniq` UNIQUE (`a_id`, `b`); ALTER TABLE `mysite_mymodelb` ADD CONSTRAINT `mysite_mymodelb_a_id_50892c78e36678b8_fk_mysite_mymodela_id` FOREIGN KEY (`a_id`) REFERENCES `mysite_mymodela` (`id`); COMMIT;
I joined the full traceback.
Attachments (2)
Change History (12)
by , 10 years ago
comment:1 by , 10 years ago
| Severity: | Normal → Release blocker |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
| Type: | Uncategorized → Bug |
comment:2 by , 10 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:3 by , 10 years ago
Bisected to 2ceb10f3b02cbebad6ed908880f49a7c3e901d12. Claude, can you advise what to do? Attaching a regression test.
by , 10 years ago
| Attachment: | 24757.diff added |
|---|
comment:4 by , 10 years ago
Wow, MySQL awesomeness!
Read http://bugs.mysql.com/bug.php?id=37910
So we have now the choice of reverting [2ceb10f3b02cbeb] and accepting that some indexes are duplicated, or try to be clever and recreate "implicit" indexes when dropping other indexes. Frankly, I now tend to choose the revert!
comment:5 by , 10 years ago
Okay with me, although it would be nice to also recommend a solution for users who have already created their schema with the current code and run into this error.
comment:8 by , 10 years ago
| Triage Stage: | Accepted → Ready for checkin |
|---|
Managed to reproduce against
stable/1.8.xandmaster.