【问题标题】:Django 1.8 migrations - CircularDependencyErrorDjango 1.8 迁移 - CircularDependencyError
【发布时间】:2015-09-08 00:00:56
【问题描述】:

我有 2 个 django 应用程序,即 main 和 authtools。当我跑步时

python manage.py 迁移

,我得到一个 CircularDependencyError:

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

在我的设置文件中,我将 AUTH_USER_MODEL 定义为:AUTH_USER_MODEL = 'authtools.User'。创建的迁移文件如下所示: 对于 authtools 应用程序,它将依赖项显示为:

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

对于主应用程序,depanncies 显示为:

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

可能出了什么问题?

【问题讨论】:

  • 文档说:Django 中的模型相互依赖可能会变得非常复杂,压缩可能会导致迁移无法运行; 然后您必须手动解决循环依赖循环,例如暴露于the documentation

标签: python django django-models django-migrations


【解决方案1】:

如果您对不同的应用程序使用 ManyToMany + 'through' 选项,而不是according to this answer,您应该:

  1. 在您使用 ManyToMany+through 的地方添加 # 注释整行 在行首
  2. makemigrations of_all_apps_you_need(也是 p1 行存在的地方)
  3. 从 p1 取消注释该行
  4. makemigrations the_app_where_the_line_from_p1_exist
  5. 迁移

如果你不使用ManyToMany,不如按照this answer,尝试类似的操作。

假设您要创建这些模型:

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)

当然你不能这样做,因为循环依赖。所以注释掉Libro模型中的外键:

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

并运行两个迁移:

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

然后取消注释 Libro 模型中的 perfile 外键并运行另一个迁移:

python manage.py makemigrations libros

【讨论】:

    【解决方案2】:

    我认为你需要关注 django 代码库的这张票:https://code.djangoproject.com/ticket/22932

    根据他们的说法,您的迁移代码应如下所示 (https://code.djangoproject.com/attachment/ticket/22932/team.0001_initial.py.diff) 或 (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      ]
    

    【讨论】:

      【解决方案3】:

      迁移的想法是您必须规划 Django 在应用模型时需要遵循的工作流程。

      假设您有两个模型,每个模型都有一个指向另一个模型的 ForeignKey。您不能创建这两个模型并进行迁移。您必须逐步应用它们。首先应用一个模型与另一个模型没有关系,然后是另一个模型(现在,可以保留与第一个模型的关系),然后是第一个模型与第二个模型的关系。逻辑思考。如果没有第二个模型,就不可能编写一个依赖另一个模型的模型。

      但这只能在第一个迁移创建过程中完成(例如,一个没有任何迁移的新应用程序)。然后,您只需维护和更新您的模型。

      【讨论】:

        【解决方案4】:

        我遇到了同样的问题,并且能够通过交换 makemigration 命令的顺序来解决它。

        以 TitanFighter 为例。无需转义模型字段,而是先为 perfiles 进行迁移,然后为 libros 迁移。

        希望这对某人有所帮助。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-11-24
          • 2015-11-12
          • 2015-06-16
          • 1970-01-01
          • 1970-01-01
          • 2018-01-14
          • 2015-12-13
          • 2015-07-11
          相关资源
          最近更新 更多