Modify

Ticket #390 (closed defect: wontfix)

Opened 4 years ago

Last modified 3 years ago

South can't handle circular app dependencies under MySQL with InnoDB

Reported by: vasili@… Owned by: andrew
Priority: major Milestone: 0.7
Component: commands Version: 0.6.2
Keywords: Cc:

Description

In the dependency documentation, one of the two rules mentioned is: "No circular dependencies (two or more migrations depending on each other)".

However, Django itself allows circular dependencies between apps:

#appone/models.py:

from django.db import models

class ThingOne(models.Model):
    name = models.CharField(max_length=20)
    related_to = models.ForeignKey("apptwo.ThingTwo")
#apptwo/models.py:

from django.db import models

from appone.models import ThingOne

class ThingTwo(models.Model):
    related_to = models.ForeignKey(ThingOne)

./manage.py syncdb does the right thing in this situation and adds foreign key constraints after creating both tables.

But if both apps are migrated with south, the migration fails when using innodb, as south tries to add the foreign key constraint for appone before creating apptwo's table.

Although the constraint of not allowing circular dependencies between migrations might make sense in other situations, here it makes south unable to deal with a legal Django model. Executing 'alter table' statements to add constraints at the end of the migration should solve this.

Attachments

Change History

comment:1 Changed 4 years ago by andrew

  • Status changed from new to closed
  • Milestone set to 0.7
  • Resolution set to wontfix
  • Reporter changed from vasili at the domain techcollective.com to vasili@…

South _does_ delay foreign keys until the end of that migration, as well as turning off InnoDB's FK checks for the duration of a migration, but the problem here is that the two migrations must run one after the other, so no matter which order you execute them in, one of the FK constraints will still always fail.

I cannot/will not fix this; it's a flaw in South's design, one might argue, but one that allows a great deal less code elsewhere. In this case, I would recommend making one of the tables without its ForeignKey?, and then adding it in a second migration, turning the circular dependency into a non-circular pair (migration with bare table first, then table with fk, then add fk to first table).

There's potential for South to detect this in future and do such a fix, but for now, this is a WONTFIX.

(Also, Trac will hide your email address from anyone else browsing the site; only people with sufficient access can see it, so there's no need to obfuscate it, as if you do, you won't get the nice emails)

comment:2 Changed 4 years ago by vasili@…

That makes sense, thanks.

comment:3 Changed 3 years ago by danny.adair@…

Just out of interest: If my current database schema has circular dependencies in its models, I can't even run an initial migration, right? Because each schemamigration is created and then executed separately.

Is it correct that the only way to "install" south in such a situation is to remove it from INSTALLED_APPS, do a regular syncdb, and then fake all migrations?

comment:4 Changed 3 years ago by andrew

No, there are alternatives; you can make a migration which does everything except a foreign key, then a second migration that adds that constraint, and then it's a solveable problem.

comment:5 Changed 3 years ago by danny.adair@…

Thanks for the quick reply!

So, for an existing database with circular dependencies, to which I retro-fit South, I have to take that initial migration, manually create a second one for those models that have a circular dependency, and move (cut/paste?) their problematic foreign key creation from the initial to the second migration? (sounds harder, but would at least allow automation on a production server)

comment:6 Changed 3 years ago by andrew

Yes, that's the only way - Django can only get away with it in syncdb as it does it all at once, so they need to be separate. It's generally a good idea to restrict circular dependencies to a single app when using South, it saves a lot of the pain, but you've got a pre-existing one, so it's a bit harder!

Also, if you have support requests in future, they're probably better off on the mailing list - every time a comment is added to an old, closed bug the original author gets an email, and it's a bit impolite, not to mention that apart from them, only I see these emails, and nobody else from the community can help you!

comment:7 Changed 3 years ago by danny.adair@…

Sorry! And thank you for the clarification. I have to mention that I did a google search for "south migrate circular dependency" and this ticket was second place. :-) Maybe these clarifications can help others. Thank you again, and I'll post future inquiries to the mailing list.

View

Add a comment

Modify Ticket

Action
as closed
The resolution will be deleted. Next status will be 'reopened'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.