#24163 closed Bug (fixed)
Migrations fail when changing from OneToOneField to ForeignKey
Reported by: | Łukasz Harasimowicz | Owned by: | Markus Holtermann |
---|---|---|---|
Component: | Migrations | Version: | 1.7 |
Severity: | Normal | Keywords: | OneToOneField ForeignKey MySQL |
Cc: | Markus Holtermann | 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
Hi!
My team and I have encountered a problem in migrations when changing relationship between models from OneToOneField to ForeignKey.
Original thread on django-users can be found here:
https://groups.google.com/forum/?#!topic/django-users/-NUbqzS4jQs
Environment
- OS: Unix (Ubuntu 14.04)/OSX
- Django: 1.7.3
- DB: MySQL 5.6.22
Steps to reproduce
- Create two models:
class Model_A(models.Model): id_A = models.AutoField(primary_key=True) class Model_B(models.Model): model_a = models.OneToOneField(Model_A)
- Make migrations and perform migration. So far everything is OK.
- Now change OneToOneField to ForeignKey:
class Model_A(models.Model): id_A = models.AutoField(primary_key=True) class Model_B(models.Model): model_a = models.ForeignKey(Model_A)
- Run migrations (makemigrations) and apply changes to db (migrate). We get this error:
we get an error:
Cannot drop index 'model_a_id': needed in a foreign key constraint
It seems that Django tries to run SQL commands in following order:
ALTER TABLE 'xxx' DROP INDEX 'yyy' and ALTER TABLE `xxx` DROP FOREIGN KEY `xxx_yyy_id_{some_hash}_fk_yyy_id`;
but if above commands are run in reverse order:
ALTER TABLE `xxx` DROP FOREIGN KEY `xxx_yyy_id_{some_hash}_fk_yyy_id`; ALTER TABLE 'xxx' DROP INDEX 'yyy' and
everything is OK.
I have created sample project where it can be reproduced (last three commits are reproducing above steps): https://github.com/harnash/django-migration-bug/commits/master
Change History (18)
comment:1 by , 10 years ago
Cc: | added |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 10 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:4 by , 10 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
comment:5 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
comment:8 by , 10 years ago
Has patch: | unset |
---|---|
Resolution: | fixed |
Status: | closed → new |
Triage Stage: | Ready for checkin → Accepted |
The recent change breaks tests on Oracle:
====================================================================== FAIL [0.001s]: test_alter_fk_to_o2o (schema.tests.SchemaTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/home/jenkins/workspace/django-oracle/database/oracle11/python/python3.4/tests/schema/tests.py", line 629, in test_alter_fk_to_o2o self.assertTrue(author_is_unique, "No unique constraint for author_id found") AssertionError: False is not true : No unique constraint for author_id found ----------------------------------------------------------------------
comment:9 by , 10 years ago
Has patch: | set |
---|
PR with Oracle fix: https://github.com/django/django/pull/3960
comment:10 by , 10 years ago
Triage Stage: | Accepted → Ready for checkin |
---|
comment:14 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:15 by , 10 years ago
Just to be sure, was the Oracle failure due to an introspection issue with get_constraints
on Oracle? If the latter, is there a ticket about it?
comment:16 by , 10 years ago
I haven't figured that out yet. But I'm investing and I'll open an issue if it's another bug.
comment:17 by , 10 years ago
The issue seems to be some kind of query caching on the cx_oracle or Oracle layer. Unless we re-connect to the database, I don't see a way to make that work.
comment:18 by , 10 years ago
I finally figured out what's going on here, and why it was hard to reproduce. The issue is actually within our control and can be solved once and for all; then we'll be able to remove the connection_persists_old_columns
database feature. See #24200.
Problem only occurs on MySQL (didn't test Oracle though)