Django migrate --fake 和 --fake-initial 解释

Django migrate --fake and --fake-initial explained

我已经使用 Django 大约 2 年了,有一个我一直害怕使用的功能:伪造迁移.

我几乎到处都看了,我能得到的最多信息来自 documentation,它指出:

--假

Tells Django to mark the migrations as having been applied or unapplied, but without actually running the SQL to change your database schema.

This is intended for advanced users to manipulate the current migration state directly if they’re manually applying changes; be warned that using --fake runs the risk of putting the migration state table into a state where manual recovery will be needed to make migrations run correctly.

--假首字母

Allows Django to skip an app’s initial migration if all database tables with the names of all models created by all CreateModel operations in that migration already exist. This option is intended for use when first running migrations against a database that preexisted the use of migrations. This option does not, however, check for matching database schema beyond matching table names and so is only safe to use if you are confident that your existing schema matches what is recorded in your initial migration.

我了解了总体思路以及为什么要使用此功能。但是,我不明白它说这是 仅供高级用户使用的部分。

谁能解释一下幕后发生的事情以及为什么需要手动恢复。

注意

我不是在寻找伪造迁移时运行的确切原始 SQL 查询。我只是想大致了解幕后发生的事情,也许还有一个为什么要伪造迁移的例子 会导致 makemigrations 无法正常工作的状态。

如果需要合并两个模型相似的分支或在它们之间切换,则与源代码中的合并冲突(git)类似的数据库问题有关。没有人故意喜欢它。

想象一下,您上周开始修改应用程序,可能是因为您发现了一个错误,或者您通过字段或 table 扩展了应用程序。今天您收到了一个更新并且遇到了问题,因为有一个迁移添加了一个仍在您的数据库中的字段并且您只能应用该迁移的其他部分。您通过 运行

查看迁移的 SQL 内容
./manage sqlmigrate some_app 0007_new_migration >customized-some_app-0007_new_migration.sql

将内容与上周所做的更改进行比较,删除或注释掉仍然适用且不能重复的命令。 运行 所有剩余 SQL 手动。将迁移标记为自动应用:

./manage migrate --fake some_app 0007_new_migration

如果你弄坏了东西,可能没人能帮你,因为迁移系统不会更多地了解数据库的当前状态。因此做好备份,写笔记,使用沙箱,精确工作。

编辑: 迁移 table django_migrations 是所有应用程序中应用的迁移的简单列表。此 table 中的行应始终与数据库结构处于同步状态。可以通过正常 migrate 应用迁移。 (或者通过反向迁移到旧状态未应用,当然通常会丢失一些数据)假迁移仅将更改应用于 django_migrations table.

me => select * from django_migrations;
 id | app      |          name           |            applied            
----+----------+-------------------------+-------------------------------
  1 | some_app | 0001_initial            | 2017-10-16 06:11:07.31249+02
  2 | some_app | 0002_auto_20171016_1905 | 2017-10-17 02:05:48.979295+02

迁移(文件)是对增量更改的描述,也是可以评估自上次迁移以来 models.py 之间差异的信息,即 运行 [=16= 时进行比较].在一些 tables 最初未被管理并且它们以后可能会被管理的情况下也足够了。 (因此也记录了非托管 table。)

编辑: 一个例子:sqlmigrate--fake 如何用于 (重新创建已删除的 table).

编辑: 示例:如果您决定删除某些应用程序的 table 并通过 migrate 重新创建它们(请注意并查看我的下面的评论),您可能还想首先通过伪迁移名称“zero”重置该应用程序的所有迁移,包括初始迁移。
./manage migrate --fake some_app zero.