--fake-initial vs --fake 在 Django 迁移中?

Posted

技术标签:

【中文标题】--fake-initial vs --fake 在 Django 迁移中?【英文标题】:--fake-initial vs --fake in Django migration? 【发布时间】:2017-07-30 10:55:16 【问题描述】:

在 Django 迁移中,--fake-initial--fake 有什么区别?使用虚假迁移有什么危险?有人知道吗?非常感谢大家。

我正在使用 django 1.10

【问题讨论】:

【参考方案1】:

嗯the documentation对此很清楚

--假初始

如果所有数据库都允许 Django 跳过应用程序的初始迁移 具有由所有 CreateModel 创建的所有模型的名称的表 该迁移中的操作已经存在。此选项旨在 用于第一次对数据库运行迁移时使用 预先存在迁移的使用。但是,此选项不检查 用于匹配表名之外的匹配数据库架构

你问的是风险,好吧

只有在您确信现有架构的情况下才能安全使用 与您初始迁移中记录的内容相匹配。

--假的

告诉 Django 将迁移标记为已应用或 未应用,但没有实际运行 SQL 来更改您的 数据库架构。

这是供高级用户操作当前 如果他们手动应用更改,则直接迁移状态;

再次明确强调风险

请注意,使用 --fake 可能会导致迁移 状态表进入需要手动恢复的状态 迁移运行正常。

这个答案不仅适用于 django 1.8+ 版本,也适用于其他版本。

2018 年 11 月编辑:我有时会在这里和其他地方看到建议您删除数据库的答案。这几乎从来都不是正确的做法。如果您删除数据库,您将丢失所有数据。

【讨论】:

关于migrate --fake and --fake-initial 的类似高级问题引用了所有这些文档段落,仍然询问它为什么有用。已经回答了如何以及何时可以在实践中足够安全地使用这些选项。【参考方案2】:

简答

--fake 应用迁移 --fake-initial 可能会,也可能不会应用迁移

更长的答案:

--fake:Django 保留一个名为django_migrations 的表,以了解它过去应用了哪些迁移,以防止您意外再次应用它们。 --fake 所做的只是将迁移文件名插入到该表中,无需实际运行迁移。如果您先手动更改数据库架构,然后再更改模型,并且想要绕过 django 的操作,这将非常有用。但是,在这一步中,您是独立的,因此请注意不要陷入不一致的状态。

--fake-initial: 取决于数据库的状态

所有表已经存在于数据库中:在这种情况下,它的工作方式类似于--fake只检查表的名称,而不检查它们的实际架构,因此,再次注意 没有任何表已存在于数据库中:在这种情况下,它就像正常迁移一样工作 某些表已存在:您收到错误消息。这不应该发生,要么你负责数据库,要么 django 负责。

请注意,--fake-initial 仅在迁移文件的类中有 initial=True 时才被考虑,否则该标志将被忽略。此外,这是 initial=True 在迁移中的唯一记录用法。

【讨论】:

【参考方案3】:

@e4c5 已经给出了关于这个问题的答案,但我想补充一点关于何时使用--fake--fake-initial

假设您有一个生产环境中的数据库,并且您希望将其用于开发和应用迁移而不破坏数据。在这种情况下,--fake-initial 就派上用场了。

--fake-initial 将强制 Django 查看您的迁移文件,并且基本上跳过创建已经在您的数据库中的表。但请注意,任何不创建表(而是修改现有表)的迁移都将运行。

相反,如果您有一个包含迁移文件的现有项目,并且想要重置现有迁移的历史记录,则通常使用--fake

【讨论】:

@heikki 感谢您的编辑建议,我的回答现在看起来更完美了。 如果您希望在不丢失现有 Django 项目中数据的情况下重置迁移,那么本文中的最后一条语句很重要。出于某种原因,我使用--fake-initial 得到table already exists 错误,如下所述:dev.to/k4ml/django-migrate---fake-initial-gotchas-2fih 解决方案是截断django_migrations 表,删除所有迁移文件,然后运行初始迁移和--fake 它们,因为数据库是已经是最新的,因此初始迁移文件被正确添加到数据库中而无需实际运行

以上是关于--fake-initial vs --fake 在 Django 迁移中?的主要内容,如果未能解决你的问题,请参考以下文章

如果 AddField 引用“相同”列,则带有“--fake-initial”的 Django 迁移不起作用

重新创建已删除的 django_migrations 表

测试软件:fake vs stub

python manage.py migrate --fake <appname> vs python manage.py migrate --fake <appname> 零

Testing.Fakes异常:无法从COR_PROFILER_PATH和COR_PROFILER环境变量解析探查器路径

TDD学习笔记一Unit Test - Stub, Mock, Fake 简介