【问题标题】:Django 1.8: Create initial migrations for existing schemaDjango 1.8:为现有模式创建初始迁移
【发布时间】:2015-07-05 10:50:42
【问题描述】:

我启动了一个使用迁移系统的 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 命令之后运行它才有效。

现在我添加一个新字段,运行makemigrations 命令,我收到以下错误:
django.db.utils.OperationalError: (1054, "Unknown column 'accounts_plan.max_item_size' in 'field list'")

我在这件事上花了好几个小时。我如何初始化迁移,以便每次都可以继续工作而不会中断迁移?

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

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

【问题讨论】:

  • 你删除了实际的表吗?还是你只是清空了它?
  • 我刚刚清空了:delete from django_migrations
  • 您可能需要drop all of the tables,而不仅仅是清空它们
  • 我在这些表中有数据,我不想删除它们。我知道我可以备份、删除、创建和恢复数据。但我有 10 张桌子,我不想那样做。我只想启动迁移。

标签: django django-migrations


【解决方案1】:

终于让它工作了,虽然我不知道为什么,但我希望它会在未来工作。
经过多次试验并浏览了 Django 的开发站点 (link)。
以下是步骤(适用于遇到此问题的人):

  1. 清空django_migrations 表:delete from django_migrations;
  2. 对于每个应用,删除其migrations 文件夹:rm -rf <app>/migrations/
  3. 重置“内置”应用程序的迁移:python manage.py migrate --fake
  4. 对于每个应用程序运行:python manage.py makemigrations <app>。注意依赖关系(具有 ForeignKey 的模型应该在其父模型之后运行)。
  5. 最后:python manage.py migrate --fake-initial

之后我运行了没有--fake-initial 标志的最后一个命令,只是为了确保。

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

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

Django 1.9 用户更新:
我在 Django 1.9.4 中再次遇到了这种情况,第 5 步失败了。
我所要做的就是将--fake-initial 替换为--fake 以使其工作。

【讨论】:

  • 我在 Django 1.8.3 的最后一步得到了RuntimeError: Error creating new content types. Please make sure contenttypes is migrated before trying to migrate apps individually.。你知道为什么吗?
  • @eric 尝试在最后一步之前运行python manage.py migrate contenttypes
  • 应记录在“如何重置迁移”下。甚至可能是一个 reset_migrations 管理命令
  • 感谢您,我在其他地方找不到如何执行此操作...这确实应该记录在案。
  • 必须从 django_migrations 中删除;然后运行 ​​python manage.py migrate。它奏效了。
【解决方案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 属性。

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

    • (对于--fake-initial 可选)将initial=True 添加到所有新的迁移类(如果添加了0002,也会添加)。

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

    断言“未检测到更改”

  5. 检查 migrate -l 是否到处显示 [x]

    断言相似:

    [X] 0001_initial

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

例子:

对于老人:

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】:

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

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

    另外我通常只运行 python manage.py makemigrations 然后只是 python manage.py migrate 即使初始迁移它应该可以在 Django 1.7 和 1.8 中正常工作。

    【讨论】:

    • 试过了,显然不行,因为migrate 命令试图创建表(已经存在)...
    • 你可以试试>> python makemigrations yourApp --initial
    • 试过了,得到:manage.py makemigrations: error: unrecognized arguments: --initial
    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 2015-06-27
      • 2014-11-19
      • 2015-03-04
      • 2011-05-05
      • 2015-08-03
      • 1970-01-01
      • 2017-09-15
      • 2015-09-08
      • 2015-09-06
      相关资源
      最近更新 更多