South 的回滚应该如何工作?

Posted

技术标签:

【中文标题】South 的回滚应该如何工作?【英文标题】:How is a rollback with South supposed to work? 【发布时间】:2011-06-09 03:52:22 【问题描述】:

让我感到困惑。假设我们有一个带有 South 迁移的 Django 项目。目前,生产项目版本为A,开发中版本为B。现在让我们假设版本B 已安装到生产环境中:

    安装新代码 运行./manage.py syncdb && ./manage.py migrate 重启网络服务器,开心就好。

下一个假设:版本B 根本不起作用。它在开发中进行了,但在生产中没有,因此必须回滚。这就是我必须遗漏的地方。我看到了两种可能性:

    重新安装旧代码。现在,向南回迁移是合适的,但是,这是不可能的,因为旧代码不包含回退所需的所有最新迁移。 我们首先回滚数据库更改,然后重新安装旧代码。但是,我们如何知道版本 A 的最新迁移?由于一个项目可以轻松数出几十个应用程序,因此您需要为每个应用程序找出哪个迁移站属于旧版本,然后分别迁移每个应用程序,然后回滚代码并希望获得最好的结果。

在这两种情况下,我都缺少关键信息,第一种情况下的迁移代码或第二种情况下的“迁移<->版本”关系。我在这里错过了什么?

PS:是的,我知道我可以从备份中恢复数据库,这就是我实际所做的。我想知道整个数据库迁移理论如何适应回滚。

【问题讨论】:

【参考方案1】:

好的。我想你正在使用版本控制?在这一点上,这对于确定“A”和“B”的构成非常重要。如果我们挥手/猜测我们引用的这个无定形代码块是“A”,而另一个我们都标记为“B”的模糊定义的东西 - 它不会起作用。

如果您尝试重新安装“A”来代替“B”,您有两种选择: 1) 从头开始​​签出和重建“A”(同步和迁移) 2) 将“B”回滚到“A”。

1) 可能无法正常工作,因为您无法杀死数据库中的数据以从无到有进行同步 2) 涉及迁移。首先,您应该在“B”而不是“A”中找到迁移。在南方,每个应用程序的所有迁移都有编号(0001、0002、0003 等)。因此,假设“B”位于 050,“A”位于 0031。当您签出“B”时,运行python manage.py migrate appname 0031 这将撤消您为“B”所做的所有数据库更改。然后在您的版本控制系统中签出“A”(“A”是否只是提交、标签或分支)

很遗憾,您不能回滚到“A”,然后说“取消迁移所有您没有的东西”。那将是一个更简单的解决方案 - 但是您需要迁移系统了解您的版本控制系统,这有点麻烦。

【讨论】:

基本上,这就是我所说的第二种可能性——大量的手动工作和某种挫败了整个向后迁移的事情,因为从备份中恢复数据库更容易而且可能更快:( 编写一个获取所需迁移文件并运行它们的脚本一点也不难。从备份恢复似乎要慢得多——尤其是随着数据库的增长。 一个更简单的解决方案可能是让 South 能够以pip freeze 的方式转储出一个列出数据库当前所在位置的文本文件。它可能只包含所有./manage migrate myapp xxxx 命令。当你在一个新分支上工作时,你会转储并保存输出,然后在你想要回滚时运行它。我猜你可以在提交之后命名文件。现在可以编写一个脚本来解析./manage migrate --list 的输出并执行此操作。【参考方案2】:

不确定这是否适合您的情况,但在将代码移回版本“A”之前您不能在生产环境中运行向后迁移吗?这样,您的数据库将返回到您执行 syncdb 之前的任何迁移,然后您将代码更改回版本 A,然后您就回到了开始的位置。

【讨论】:

以上是关于South 的回滚应该如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

如何撤消 TFS 中的回滚?

如何创建表的回滚副本以防我插入或更新错误

如何清除 Tmux 中的回滚缓冲区?

简单了解Oracle的回滚段

如果实现oracle中DDL语句的回滚

不小心merge后的回滚操作