南方: 如何在生产服务器上还原迁移?
南方: 如何在生产服务器上还原迁移?
我想通过运行其Migration.backwards()
方法来恢复我的最后一次迁移(0157)。由于我要在生产服务器上还原迁移,我希望在代码部署期间自动运行它。部署脚本执行以下步骤:
- 拉取代码更改
- 运行迁移:
manage.py migrate
- 刷新Apache以使用最新的代码:
touch django.wsgi
如果可以的话,我会创建一个新的迁移文件,告诉South向后迁移到0156:
migrations/0158_backward__migrate_to_0156.py
这个提交的迁移将部署到生产环境,并在manage.py migrate 这些答案中执行。
假设我创建了两个数据迁移,第一个是用户的Payment,第二个是User模型。我已经为这两个迁移中的每个都实现了backwards()方法,以防需要还原这些数据迁移。我已经将这两个迁移部署到生产环境。突然发现Payment迁移包含一个错误。我想尽快撤销我最后的两个数据迁移。最快安全的方法是什么?
在生产服务器上如何还原迁移?
问题的出现原因是:开发人员决定最后一个迁移不是一个好主意,希望回滚到之前的版本。有两种情况需要考虑:
(a) 迁移 #157 还没有发布或部署到任何地方。
解决方法是从 models.py 中撤销最后的更改,并从源代码存档中删除迁移 #157.py。任何部署都会将系统还原到第 156 级;"157 从未存在过"。
(b) 最新的软件已经部署了迁移 #157。
在这种情况下,前面的策略显然行不通。所以你需要创建一个迁移 #158 来撤销 #157。撤销 models.py 中的更改,然后运行以下代码:
django manage.py migrate0157 django manage.py schemamigration --auto
这将自动生成一个新的迁移 #158,其中包含与 #157 相反的模式迁移。
如果 schemamigration 因为 Django 模型验证的问题而出现麻烦(如果你有自定义验证器,检查 ORM 之外的内容,这种情况可能会发生),我建议使用以下解决方法:
/ /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--auto
你是不是想说的是 `manage.py migrationcheck
我之前没有意识到 checkmigrations 实际上是我们很久以前创建的一个自定义命令 🙂 我已经在这个主题上编辑了帖子,参见上文。
问题的原因:在生产服务器上回滚迁移时,希望在代码部署期间自动运行。
解决方法:运行manage.py migrate <app>
来应用所有现有的迁移,然后撤销模型中的更改,并运行manage.py schemamigration <app> --auto
创建一个新的迁移,该迁移有效地撤销了之前的迁移。最后再次运行manage.py migrate <app>
应用新的迁移。
另一个解决方法是使用Migration.backwards()
方法来回滚迁移,而不是创建全新的迁移。这对于手动实现的datamigration
迁移是必需的。
但是,如果要将backwards()
作为一个新的独立迁移运行,那么请澄清问题。只有在向后迁移(即迁移到低于当前版本的版本)时,才会运行backwards()
。
无论如何,以上方法都会创建一个向前迁移的迁移,因为本质上这就是你想要的。
然而,如果有这种情况:我创建了两个数据迁移,第一个是用户的Payment,第二个是User模型。我已经实现了两个迁移的backwards()
方法以防需要回滚这些数据迁移。我已经将这两个迁移部署到生产环境中。突然发现Payment迁移中存在错误。我希望尽快回滚最后两个数据迁移。按照你的解决方法,我将不得不将backwards()
逻辑从这两个迁移中导出到新的迁移中,这可能需要一段时间,并且复制代码可能会导致错误。
除了更改部署过程以处理特定的迁移(这样您可以要求它运行,比如迁移0157),我没有看到其他解决方法。您可以编写一个向前迁移,它只是调用另一个迁移的backwards()
,但我认为这并不安全,因为它会破坏South的工作方式。
问题的出现的原因:在生产服务器上如何还原迁移。
解决方法:在开发环境中手动回滚到0156版本,然后手动更新迁移历史表,以便欺骗South以为你仍然是在0156版本,然后再次运行schemamigration。无法保证能够成功,但值得一试。
标准的方式是在生产服务器上还原数据库模式更改而无需停机。
我的建议是在开发环境中执行这个操作,然后将新创建的迁移部署到服务器上。而且没有办法在没有任何停机的情况下运行迁移。
我将代码部署到生产环境,运行迁移并触发django.wsgi。新的迁移被提交,代码几乎同时刷新。我认为没有停机(可能只有几分之一秒)。
是的,停机时间可能很短,但确实存在。在迁移运行和进程重新启动之间,可能会发生一些500错误;这取决于流量和迁移所做的工作。我提出的解决方案不涉及对生产数据库迁移历史的任何手动调整,只涉及开发环境。
文章:
在生产服务器上如何还原迁移?
在开发环境中,我们可以通过手动回滚到0156版本并更新迁移历史表来欺骗South,以便在认为我们仍然处于0156版本的情况下重新运行schemamigration。虽然无法保证成功,但这个方法可能值得一试。
然而,在生产服务器上,我们需要找到一种标准的方式来还原数据库模式更改而无需停机。有人建议在开发环境中执行这个操作,然后将新创建的迁移部署到服务器上。然而,这并不意味着我们可以在没有任何停机的情况下运行迁移。
某些情况下,他们将代码部署到生产环境,运行迁移并触发了django.wsgi。新的迁移被提交,代码几乎同时刷新。他认为没有停机(可能只有几分之一秒)。然而,实际上,停机时间可能很短,但确实存在。在迁移运行和进程重新启动之间,可能会发生一些500错误;这取决于流量和迁移所做的工作。
因此,为了避免这些问题,我们需要找到一种在生产服务器上还原迁移的方法,而无需停机。这样我们就不会影响到用户的访问。
虽然目前还没有找到完美的解决方案,但这个问题仍然值得我们深入探讨,以寻找一个更好的解决方法。