Django 1.8 migrations - CircularDependencyError

9.9k views Asked by At

I have 2 django apps i.e. main and authtools. When I run

python manage.py migrate

, I get a CircularDependencyError:

raise CircularDependencyError(", ".join("%s.%s" % n for n in cycle))
django.db.migrations.graph.CircularDependencyError: main.0001_initial, authtools.0001_initial

In my setting file I have the AUTH_USER_MODEL defined as such:AUTH_USER_MODEL = 'authtools.User' . The migration files created look like this: For the authtools app, it shows dependancies as:

dependencies = [
        ('main', '__first__'),
        ('auth', '0001_initial'),
    ]

And for the main app, the depandancies are shown as:

dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

What could be wrong?

4

There are 4 answers

0
sadaf2605 On

I think you need to follow this ticket of django code base: https://code.djangoproject.com/ticket/22932

According to them your migration code should look like either this (https://code.djangoproject.com/attachment/ticket/22932/team.0001_initial.py.diff) or(https://code.djangoproject.com/attachment/ticket/22932/team.0002_auto_20140704_1453.py):

# -*- coding: utf-8 -*-
2   from __future__ import unicode_literals
3   
4   from django.db import models, migrations
5   from django.conf import settings
6   
7   
8   class Migration(migrations.Migration):
9   
10      dependencies = [
11          migrations.swappable_dependency(settings.AUTH_USER_MODEL),
12          ('team', '0001_initial'),
13      ]
14  
15      operations = [
16          migrations.CreateModel(
17              name='TeamCaptain',
18              fields=[
19                  ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
20                  ('rider', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
21                  ('team', models.ForeignKey(to='team.Team')),
22              ],
23              options={
24              },
25              bases=(models.Model,),
26          ),
27      ]
0
trd On

The idea with migrations is that you have to plan the workflow that Django needs to follow when applying your models.

Let's say you have two models and each of one has a ForeignKey to the other one. You cannot create these two models and makemigrations. You have to apply them step by step. First apply one model without the relation to the other one, then the other model (now, the relation to the first one can be kept) and then the first model's relation to the second. Think logical. It's impossible to write a model which relies on another one without having the second one.

But this has to be done just for the first migrations creation process (e.g. a new application without any migration). Then you just maintain and update your models.

0
TitanFighter On

If you use ManyToMany + 'through' option to different application, than according to this answer you should:

  1. Comment a whole line where you use ManyToMany+through by putting # at the beginning of the line
  2. makemigrations of_all_apps_you_need (also the one where the line from p1 exist)
  3. uncomment the line from p1
  4. makemigrations the_app_where_the_line_from_p1_exist
  5. migrate

If you dont use ManyToMany, than according to this answer, try similar actions.

Lets suppose that you want to create these models:

libros/models.py:

class Libro(models.Model):
    name = models.CharField(max_length=20)
    perfile = models.ForeignKey('perfiles.Perfile', null=True)

perfiles/models.py:

class Perfile(models.Model):
    name = models.CharField(max_length=20)
    libro = models.ForeignKey('libros.Libro', null=True)

Of course you can't do it because of the circular dependency. So comment out foreign key in the Libro model:

class Libro(models.Model):
    name = models.CharField(max_length=20)
    # perfile = models.ForeignKey('perfiles.Perfile', null=True)

And run two migrations:

python manage.py makemigrations libros
python manage.py makemigrations perfiles

After that uncomment the perfile foreign key in the Libro model and run another migration:

python manage.py makemigrations libros
0
Wreeecks On

I've experienced the same issue and was able to resolve it by interchanging the order of makemigration command.

Using TitanFighter's example. There's no need to escape model fields, instead makemigration for perfiles first then migrations for libros.

Hopefully this helps someone.