Django 1.8:为现有模式

时间:2015-04-27 05:44:40

标签: django django-migrations

我开始使用迁移系统的django 1.8项目 在某种程度上事情变得混乱,所以我从数据库中删除了迁移文件夹和表,现在我试图重建它们,但没有成功。

我有三个应用程序(3个models.py个文件),模型完全反映了这些表格!

到目前为止,我发现的最佳方法是:

  1. 删除所有migrations个文件夹。完成!
  2. django_migrations表中删除所有内容。完成!
  3. 为每个应用运行python manage.py makemigrations --empty <app>。完成!
  4. 运行python manage.py migrate --fake。完成! (虽然只有在每次makemigrations命令之后运行它才有效。
  5. 现在我添加一个新字段,运行makemigrations命令,我收到以下错误:
    django.db.utils.OperationalError: (1054, "Unknown column 'accounts_plan.max_item_size' in 'field list'")

    我已经在这件事上燃烧了HOURS。我怎样才能初始化迁移,这样我每次都可以继续工作而不会发生迁移中断?

    为什么这么复杂?为什么没有一个简单的单行:initiate_migrations_from_schema

    编辑:
    现在事情变得更加糟糕了。我截断了django_migrations表并删除了所有migrations文件夹 现在我尝试运行python manage.py migrate --fake-initial(我在DEV文档中找到的东西),这样就设置了所有Django&#39;内部&#39;应用程序(身份验证,会话等)和我得到:
    (1054, "Unknown column 'name' in 'django_content_type'")
    现在,这个&#34;列&#34;不是一个真正的专栏。它是Django @property应用中定义的contenttypes。这里发生了什么?为什么将name属性标识为真正的列?

5 个答案:

答案 0 :(得分:160)

终于开始工作了,虽然我不知道为什么,我希望它能在将来发挥作用。
经过多次试验并通过Django的开发站点(link) 以下是步骤(对于遇到此问题的人):

  1. 清空django_migrations表:delete from django_migrations;
  2. 对于每个应用,请删除其migrations文件夹:rm -rf <app>/migrations/
  3. 重置&#34;内置&#34;的迁移应用:python manage.py migrate --fake
  4. 对于每个应用运行:python manage.py makemigrations <app>。处理依赖关系(具有ForeignKey的模型应该在其父模型之后运行)。
  5. 最后:python manage.py migrate --fake-initial
  6. 之后我运行了最后一个没有--fake-initial标志的命令,只是为了确保。

    现在一切正常,我可以正常使用迁移系统。

    我确定我不是唯一遇到此问题的人。必须更好地记录,甚至简化。

    Django 1.9用户更新:
    我用Django 1.9.4再次出现了这个场景,第5步失败了 我所要做的就是将--fake-initial替换为--fake以使其正常工作。

答案 1 :(得分:2)

我遇到过这种情况,但我从来没有放弃数据库来解决它。通常,我会从应用程序中删除迁移文件夹,并从数据库中删除迁移条目。

我会尝试一次运行一个应用程序进行迁移。如果任何应用程序依赖其他表格,那么显然最后添加它们。

此外,我通常只运行 python manage.py makemigrations ,然后只需 python manage.py migrate 即使初始迁移,它也可以与Django 1.7和1.8一起使用。

答案 2 :(得分:2)

django ...,1.8,1.9,...

您希望实现的目标是压缩现有迁移并使用替换。

如何在发布时不使用任何命令(一个不影响数据库和同事的情况)正确执行。

  1. 对于每个应用,请删除其迁移文件夹: mv <app>/migrations/ <app>/migrationsOLD/

  2. 对于每个应用运行:python manage.py makemigrations <app>

  3. 自定义每个新迁移:

    • 如果您有复杂应用,或者有更多应用和相关模型,请避免CircularDependencyErrorValueError: Unhandled pending operations for models

      <app> 0002_initial2.py准备第二次空迁移(将依赖关系设置为app_other::0001_initial.py<app> :: 0001_initial.py - 所有ForeignKey,M2M都与在其他应用程序的0001迁移步骤中创建的模型)

      所有必须按顺序排列 - 有时需要更多迁移才能准备。在每次迁移中处理dependencies属性。

    • 处理初始值 - 验证来自RunPython的所有migrationsOLD操作,并在必要时将代码复制到新的初始迁移。

    • --fake-initial的可选项)将initial=True添加到所有新的迁移类中(如果已添加,则为0002)。

    • 在新的迁移类中添加replaces属性。 (比如自己的自定义squashmigrations)。放置<app>
    • 中的所有旧迁移
  4. 使用makemigrations验证所有内容。

    断言“未检测到任何变化”

  5. 检查migrate -l是否显示[x]无处不在

    断言类似:

    [X] 0001_initial

    [X] 0002_initial2(102次压缩迁移)

  6. 示例:

    对于旧的:

    0001_initial.py
    0002_auto.py
    ...
    0103_auto.py
    

    制备

    0001_initial.py
    0002_initial2.py  (optional but sometimes required to satisfy dependency)
    

    并添加到replaces到最后一个(此处为0002,可以是0001):

    replaces = [(b'<app>', '0002_auto.py'), ..., (b'<app>', '0103_auto.py')]
    

    0001_initial.py的名称应与旧名称相同。

    0002_initial2.py是新的,但它可以替代旧的迁移,因此Django会将其视为已加载。

答案 3 :(得分:0)

如果您使用的是路由器,可能会出现问题。检查方法allow_migrate是否在routers.py中以正确的方式执行。尝试将返回值始终设置为True,并检查它是否解决了问题,

def allow_migrate(self, db, app_label, model_name=None, **hints):
    return True

答案 4 :(得分:-1)

谢谢 - 我一直在研究这个问题,你的最佳实践列表非常方便。这可能有助于新手像我这样的python:

如果您从一组现有模型开始,请清除以前的所有迁移过程!

我的情况是我开始使用sqlite只是为了理解django然后切换到一个mysql数据库 - 并且它不断抛出1053错误,可能尝试应用之前的迁移它没有资源来解决...