【问题标题】:Django: revert merge migrationDjango:还原合并迁移
【发布时间】:2017-08-22 01:02:03
【问题描述】:

假设我们有以下依赖关系图的迁移(全部应用):Initial state

现在,出于某种原因,我们希望在应用迁移0006_f 后将数据库模式恢复为状态。我们输入:

./manage.py migrate myapp 0006_f

现在我们有以下状态:One branch reverted

问题是 Django 不恢复右分支,所以现在我们从左分支应用了一些迁移,从右分支应用了一些迁移。

避免这种情况的一种方法是迁移回0002_b 并转发到0006_f,但这可能会导致数据丢失。还有一些迁移0006_f0005_e0004_d0003_c 可能是不可逆的。

另一种方法是运行以下命令:

./manage.py migrate myapp 0006_f
./manage.py migrate myapp 0004_d1

现在,要达到所需的状态,我们只需要恢复迁移0004_d1,我看不到在不撤消 0006_f0005_e0004_d 的情况下撤消 0004_d1 的方法,除了打开 DB shell并手动还原。

有没有办法明确撤消一个迁移?是否有另一种方法可以正确撤消并行分支的迁移?撤消合并迁移时,Django是否有某些理由不自动从并行分支恢复迁移?

【问题讨论】:

    标签: python django database-migration django-migrations


    【解决方案1】:

    于 2019 年 10 月 17 日编辑:我添加了一个步骤 0,我发现在涉及跨应用依赖项时可以降低一些风险。

    如果我没看错你的问题,那么你的情况与我类似,我想在不触及其他分支的情况下还原一个特定的分支。

    我通过以下步骤设法做到了这一点(在 v1.11.7 和 v2.2 中):

    1. 反向迁移到要取消应用的每个分支的第一个节点 (0004_d1)
    2. 伪造向共同祖先(0003_c)的反向迁移编辑:见底部注释
    3. fake 迁移到要还原的每个分支的第一个节点 (0004_d1)
    4. 从步骤 1 (0003_c) 反向迁移到共同祖先
    5. 伪造迁移到您要保留的分支的尖端 (0007_g)
    6. 根据需要删除或修改合并迁移;见下文 (0008_merge)

    所以在你的情况下:

    ./manage.py migrate 0004_d1
    ./manage.py migrate --fake myapp 0003_c
    ./manage.py migrate --fake myapp 0004_d1
    ./manage.py migrate myapp 0003_c
    ./manage.py migrate --fake myapp 0007_g
    

    如果您的合并迁移 0008_merge 进行任何实际工作或迁移更多分支,您可能必须手动编辑它以省略 0005_e1 分支,然后假迁移到它;否则你应该可以删除它。

    编辑:关于第 2 步的注意事项:似乎有时,如果第 2 步导致某些跨应用依赖迁移被假未应用,它们可能会导致第 4 步失败。第 1 步可降低此风险,但您应检查已应用哪些操作,并尝试确保在第 4 步期间任何跨应用依赖项均未处于伪造状态。

    【讨论】:

      猜你喜欢
      • 2021-12-18
      • 2021-07-29
      • 2018-08-01
      • 2013-05-23
      • 1970-01-01
      • 1970-01-01
      • 2022-10-26
      • 2014-09-17
      • 2021-09-20
      相关资源
      最近更新 更多