【问题标题】:South: how to revert migrations in production server?South:如何恢复生产服务器中的迁移?
【发布时间】:2014-01-11 22:15:19
【问题描述】:

我想通过运行 Migration.backwards() 方法来恢复我上次的迁移 (0157)。由于我正在恢复生产服务器中的迁移,因此我想在代码部署期间自动运行它。部署脚本执行以下步骤:

  1. 拉取代码更改
  2. 运行迁移:manage.py migrate <app>
  3. 刷新 Apache 以使用最新代码:touch django.wsgi

如果可以的话,我会创建 新的迁移文件,告诉 South 向后迁移到 0156:

migrations/0158_backward__migrate_to_0156.py

此提交的迁移将部署到生产环境并在manage.py migrate <app> 命令期间执行。在这种情况下,我不必像 these answers 中建议的那样手动执行向后迁移。

可以说,我创建了两个数据迁移,第一个用于用户的支付,第二个用于用户模型。我已经为这两种迁移实现了 backwards() 方法,以防我不得不恢复这些数据迁移。我已将这两个迁移部署到生产环境。突然发现支付迁移有错误。我想尽快恢复我最后的两次数据迁移。最快安全的方法是什么?

【问题讨论】:

标签: python django migration django-south dev-to-production


【解决方案1】:

由于我要在生产服务器中恢复迁移,因此我想运行 它会在代码部署期间自动进行。

恕我直言,最安全的路径是

  1. 运行 manage.py migrate <app>(即应用所有现有迁移,即最多 0156)
  2. 撤消模型中的更改
  3. 运行manage.py schemamigration <app> --auto

这将创建一个新的迁移 0157,它有效地恢复了之前的迁移 0156。然后只需再次运行 manage.py migrate <app> 即可应用新的迁移。据我了解,您的代码部署就是这样做的。

【讨论】:

  • 我更喜欢使用Migration.backwards() 方法来还原迁移,而不是创建全新的迁移。这是手动实现的datamigration 迁移所必需的。
  • @niekas 请澄清您的问题,您在哪里说“但我想将它作为新的单独迁移运行。”您不能通过将其作为单独的向前迁移运行来运行向后(),向后()是仅当您返回返回时才运行(即迁移到低于当前版本的版本)
  • @nikas 我坚持我的回答。如果它创建了 forwards() 迁移,请不要担心,因为本质上这就是您想要的。
  • 但是这个场景怎么样:我创建了两个数据迁移,第一个用于用户的支付,第二个用于用户模型。我已经为这两种迁移实现了backwards() 方法,以防我不得不恢复这些数据迁移。我已将这两个迁移部署到生产环境。突然发现支付迁移有错误。我想尽快恢复我最后的两次数据迁移。使用您的解决方案,我必须将两个迁移中的 backwards() 逻辑导出到新的迁移中,这需要一段时间,并且复制代码可能会导致错误。
  • 我明白了。除了改变部署过程来处理特定的迁移(所以你可以要求它运行,比如说,迁移 0157,我没有看到除此之外的任何其他方式。你也许可以编写一个 forwards() 迁移,它只是调用另一个迁移迁移是向后的(),但我认为这不安全,因为它破坏了南方的工作方式。
【解决方案2】:

显然,代码线已迁移到 #157,现在开发人员认为最后一个毕竟不是一个好主意。所以计划是回到#156。

两种情况:

(a) 迁移 #157 尚未在任何地方发布或部署。 只需从 models.py 中恢复上一次更改并从源存档中删除迁移 #157.py。任何部署都会将系统提升到 156 级; “157 从来没有出现过”。

(b) 已经部署了带有迁移 #157 的最新软件。 在这种情况下,前面的策略显然行不通。因此,您需要创建迁移 #158 以撤消 #157。还原 models.py 中的更改并运行

django manage.py migrate <app> 0157
django manage.py schemamigration <app> --auto

这将自动生成一个新的迁移 #158,其中将包含与 #157 相比的反向架构迁移。

如果由于 django 模型验证而导致 schemamigration 出现问题(如果您有自定义验证器来检查 ORM 框之外的内容,则可能会发生这种情况),我建议采用以下解决方法:

<django project>/<app>/management/commands/checkmigrations.py

from south.management.commands import schemamigration
class Command(schemamigration.Command):
    requires_model_validation = False
    help = "schemamigration without model validation"

此命令在 manage.py 中可用:

django manage.py checkmigrations <app> --auto

【讨论】:

  • 您的意思是manage.py migrationcheck &lt;app&gt;?这两行代码只运行迁移而不生成任何文件。
  • 我没有意识到 checkmigrations 实际上是我们很久以前创建的自定义命令 :) 我已经编辑了关于这个主题的帖子,见上文。
【解决方案3】:

这里没有灵丹妙药。我能想到的最简单的解决方案是——当然是在你的开发环境中——手动迁移回 0156,手动更新你的迁移历史表(对不起,我现在不记得表的名字了)来愚弄南方,以为你是仍然是 @0158,然后再次运行 schemamigration。不保证工作,但可能值得一试。

【讨论】:

  • 似乎不对。在不停机的情况下恢复生产服务器中的数据库架构更改的标准方法是什么?
  • 我的建议是在您的开发环境中执行此操作,然后将新创建的迁移部署到您的服务器。并且没有方法可以在不停机的情况下运行迁移。
  • 我将代码部署到生产环境,运行迁移和touch django.wsgi。几乎同时提交新的迁移和代码刷新。我认为没有停机时间(可能只有一秒钟的时间)。
  • 是的,停机时间可能很短,但确实存在。从运行迁移到重新启动进程之间,您可能会发生 500 个错误;取决于流量和你的迁移做了什么。而且我建议的解决方案并不意味着对生产数据库上的迁移历史进行任何手动调整 - 仅在 dev 上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-09
  • 2018-03-23
  • 1970-01-01
  • 2018-07-18
  • 1970-01-01
相关资源
最近更新 更多