Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#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

  1. 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)
  1. Make migrations and perform migration. So far everything is OK.
  1. 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)
  1. 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 Changed 3 years ago by Markus Holtermann

Cc: Markus Holtermann added
Triage Stage: UnreviewedAccepted

Problem only occurs on MySQL (didn't test Oracle though)

comment:2 Changed 3 years ago by Markus Holtermann

Owner: changed from nobody to Markus Holtermann
Status: newassigned

comment:3 Changed 3 years ago by Markus Holtermann

Has patch: set

comment:4 Changed 3 years ago by Tim Graham

Triage Stage: AcceptedReady for checkin

comment:5 Changed 3 years ago by Markus Holtermann <info@…>

Resolution: fixed
Status: assignedclosed

In 5792e6a88c1444d4ec84abe62077338ad3765b80:

Fixed #24163 -- Removed unique constraint after index on MySQL

Thanks Łukasz Harasimowicz for the report.

comment:6 Changed 3 years ago by Markus Holtermann <info@…>

In e55cb91bd47d054d502c03cdbe74ac98986af3fb:

[1.8.x] Fixed #24163 -- Removed unique constraint after index on MySQL

Thanks Łukasz Harasimowicz for the report.

Backport of 5792e6a88c1444d4ec84abe62077338ad3765b80 from master

comment:7 Changed 3 years ago by Markus Holtermann <info@…>

In db2a97870d74bc689428d9c2a942115ef799f2d2:

[1.7.x] Fixed #24163 -- Removed unique constraint after index on MySQL

Thanks Łukasz Harasimowicz for the report.

Backport of 5792e6a88c1444d4ec84abe62077338ad3765b80 from master

comment:8 Changed 3 years ago by Markus Holtermann

Has patch: unset
Resolution: fixed
Status: closednew
Triage Stage: Ready for checkinAccepted

The recent change breaks tests on Oracle:

http://djangoci.com/job/django-oracle/lastCompletedBuild/database=oracle11,python=python3.4/testReport/schema.tests/SchemaTests/test_alter_fk_to_o2o/

======================================================================
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 Changed 3 years ago by Markus Holtermann

Has patch: set

comment:10 Changed 3 years ago by Tim Graham

Triage Stage: AcceptedReady for checkin

comment:11 Changed 3 years ago by Markus Holtermann <info@…>

In 64ecb3f07db4be5eef4d9eb7687f783ee446c82f:

Refs #24163 -- Fixed failing Oracle test when migrating from ForeignKey to OneToOneField

Thanks Tim Graham for review

comment:12 Changed 3 years ago by Markus Holtermann <info@…>

In 20f1aafa14798d8caac74319a335668ffe86c224:

[1.8.x] Refs #24163 -- Fixed failing Oracle test when migrating from ForeignKey to OneToOneField

Thanks Tim Graham for review

Backport of 64ecb3f07db4be5eef4d9eb7687f783ee446c82f from master

comment:13 Changed 3 years ago by Markus Holtermann <info@…>

In 70845c6809f53d9d4029d760aa0118a47b92cb9d:

[1.7.x] Refs #24163 -- Fixed failing Oracle test when migrating from ForeignKey to OneToOneField

Thanks Tim Graham for review

Backport of 64ecb3f07db4be5eef4d9eb7687f783ee446c82f from master

comment:14 Changed 3 years ago by Markus Holtermann

Resolution: fixed
Status: newclosed

comment:15 Changed 3 years ago by Claude Paroz

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 Changed 3 years ago by Markus Holtermann

I haven't figured that out yet. But I'm investing and I'll open an issue if it's another bug.

comment:17 Changed 3 years ago by Markus Holtermann

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 Changed 3 years ago by Shai Berger

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.

Note: See TracTickets for help on using tickets.
Back to Top