Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#23071 closed Bug (fixed)

Can't create migration for apps that have ForeignKeys to each other

Reported by: Jeroen Dekkers Owned by: nobody
Component: Migrations Version: 1.7-rc-1
Severity: Release blocker Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

ForeignKey's to other apps create a dependency on __latest__ migration of that app. Because of this we can't create migrations where we have ForeignKey relations that go both ways, because that would result in app1 depending on __latest__ of app2 and app2 depending on __latest__ of app1. Way to reproduce:

Create the following model in myapp1:

class Model1(models.Model):
    field = models.CharField(max_length=10)

And the following model in myapp2:

class Model2(models.Model):
    field = models.CharField(max_length=10)

We run makemigations creating both initial migrations. We then add the following model in myapp1:

class Model3(models.Model):
    model2 = models.ForeignKey('myapp2.Model2')

We run makemigrations again, this will create a myapp1 migration that depends on __latest__ of myapp2.

Then we add the following model to myapp2:

class Model4(models.Model):
    model1 = models.ForeignKey('myapp1.Model1')

We then run makemigrations again, this will create a myapp2 migration that depends on __latest__ of myapp1. Running migrate then gives us a circular dependency error:

django.db.migrations.graph.CircularDependencyError: [('myapp1', u'0002_model3'), ('myapp2', u'0002_model4'), ('myapp1', u'0002_model3')]

I think the correct way to create dependency would be to create an explicit dependency on the latest migration of the other app at the time of creating the new ForeigKey instead of using __latest__. This will mean that the second myapp1 migration will depend on myapp2's 0001_initial, and the second myapp2 migration will depend on myapp1's 0002_model3.

I tested this and it seems to work fine.

Change History (5)

comment:1 Changed 9 years ago by Jeroen Dekkers

Has patch: set

comment:2 Changed 9 years ago by Florian Apolloner

Triage Stage: UnreviewedAccepted

Yeah, latest also doesn't work if at some point the target of the FK is deleted :/

comment:3 Changed 9 years ago by Jeroen Dekkers <jeroen@…>

Resolution: fixed
Status: newclosed

In 3582698c138a7a311d12a57d0b35359815e8dbc9:

Fixed #23071 -- Use last migration's name in dependency to other app

Changed the autodetector to lookup the name of the other app's last
migration in the graph and use that as dependency instead of using
latest.

comment:4 Changed 9 years ago by Andrew Godwin <andrew@…>

In ed4812692e3a103444303b0a3dd1429bbdf9511c:

Merge pull request #2938 from dekkers/ticket_23071

Fixed #23071 -- Use last migration's name in dependency to other app

comment:5 Changed 9 years ago by Andrew Godwin <andrew@…>

In 6e7e5bacd51d1ab4411c58eea04a137639a0a354:

[1.7.x] Fixed #23071 -- Use last migration's name in dependency to other app

Changed the autodetector to lookup the name of the other app's last
migration in the graph and use that as dependency instead of using
latest.

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