简体   繁体   English

南:如何在生产服务器中恢复迁移?

[英]South: how to revert migrations in production server?

I want to revert my last migration (0157) by running its Migration.backwards() method. 我想通过运行其Migration.backwards()方法来恢复上次迁移(0157)。 Since I am reverting the migration in production server I want to run it automatically during code deployment. 由于我要恢复生产服务器中的迁移,我想在代码部署期间自动运行它。 Deployment script executes these steps: 部署脚本执行以下步骤:

  1. Pull code changes 拉代码更改
  2. Run migrations: manage.py migrate <app> 运行迁移: manage.py migrate <app>
  3. Refresh Apache to use newest code: touch django.wsgi 刷新Apache以使用最新代码: touch django.wsgi

If I could, I would create new migration file which would tell South to backward migrate to 0156: 如果可以,我会创建新的迁移文件 ,告诉South向后迁移到0156:

migrations/0158_backward__migrate_to_0156.py

This commited migration would be deployed to production and executed during manage.py migrate <app> command. 此提交的迁移将部署到生产并在manage.py migrate <app>命令期间执行。 In this case I wouldn't have to execute backward migration by hand, like suggested in these answers . 在这种情况下,我不必像在这些答案中建议的那样手动执行向后迁移。

Lets say, I have created two data migrations, first for user's Payment, second for User model. 可以说,我创建了两个数据迁移,首先是用户付款,第二个是用户模型。 I have implemented backwards() methods for both migrations in case I'd have to revert these data migrations. 我已经为迁移实现了backwards()方法,以防我必须恢复这些数据迁移。 I've deployed these two migrations to production. 我已将这两个迁移部署到生产中。 And suddenly find out that Payment migration contains an error. 并突然发现付款迁移包含错误。 I want to revert my two last data migrations as fast as possible. 我想尽快恢复我最近的两次数据迁移。 What is the fastest safe way to do it? 什么是最快的安全方法呢?

Since I am reverting the migration in production server I want to run it automatically during code deployment. 由于我要恢复生产服务器中的迁移,我想在代码部署期间自动运行它。

IMHO the safest path is 恕我直言最安全的道路是

  1. run manage.py migrate <app> (ie apply all existing migrations, ie up to 0156) 运行manage.py migrate <app> (即应用所有现有迁移,即最多0156)
  2. undo the changes in your model 撤消模型中的更改
  3. run manage.py schemamigration <app> --auto 运行manage.py schemamigration <app> --auto

This will create a new migration 0157 that effectively reverts the previous migration 0156. Then simply apply the new migration by running manage.py migrate <app> again. 这将创建一个新的迁移0157,可以有效地恢复先前的迁移0156.然后,只需再次运行manage.py migrate <app>即可应用新的迁移。 As I understand, your code deployment will just do that. 据我了解,您的代码部署就是这样做的。

There's no silver bullet here. 这里没有银弹。 The simplest solution I can think of would be to - in your dev env of course - manually migrate back to 0156, manually update your migration's history table (sorry I can't remember the table's name now) to fool south in thinking you're still @0158, then run schemamigration again. 我能想到的最简单的解决方案是 - 在您的开发环境中 - 当然 - 手动迁移回0156,手动更新您的迁移历史表(抱歉我现在不记得表的名称)愚弄南方认为你是仍然是@ 0158,然后再次运行schemamigration。 Not garanteed to work but might be worth trying. 不保证工作,但可能值得尝试。

Apparently the codeline has migrations up to #157 and now the developer decided that the last one was not a good idea after all. 显然,代码行的迁移速度高达#157,现在开发人员认为最后一个不是一个好主意。 So the plan is to go back to #156. 所以计划是回到#156。

Two scenarios: 两种情况:

(a) migration #157 was not released or deployed anywhere yet. (a)迁移#157尚未在任何地方发布或部署。 Simply revert the last change from models.py and delete migration #157.py from the source archive. 只需从models.py恢复最后一个更改,然后从源存档中删除迁移#157.py。 Any deployment will take the system to level 156; 任何部署都会使系统达到156级; "157 was never there". “157从来没有”。

(b) there have been deployments of the latest software with migration #157. (b)部署了最新的软件,迁移#157。 In this case the previous strategy will obviously not work. 在这种情况下,先前的策略显然不起作用。 So you need to create a migration #158 to undo #157. 因此,您需要创建迁移#158以撤消#157。 Revert the change in models.py and run 还原models.py中的更改并运行

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

This will auto-generate a new migration #158, which will contain the inverse schema migration compared to #157. 这将自动生成一个新的迁移#158,它将包含与#157相比的反向模式迁移。

If schemamigration is giving trouble because of django Model validation (something that can happen if you have custom validators which check stuff outside the ORM box), I suggest the following workaround: 如果由于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"

This command becomes available in manage.py: 该命令在manage.py中可用:

django manage.py checkmigrations <app> --auto

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM