--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 迁移不起作用
python manage.py migrate --fake <appname> vs python manage.py migrate --fake <appname> 零
Testing.Fakes异常:无法从COR_PROFILER_PATH和COR_PROFILER环境变量解析探查器路径