使用 Django South 重置迁移历史的推荐方法是什么?

我已经使用 South (0.7)和 Django (1.1.2)积累了相当多的迁移,它们开始在我的单元测试中消耗相当多的时间。我想重新设置基线并开始一组新的迁移。我回顾了 南方文件,进行了常规的 Google/Stackoverflow 搜索(例如“ django South (重置或删除或移除)迁移历史”) ,没有发现任何明显的结果。

我考虑过的一种方法是“重新开始”,即手动“删除”South 或“清除”历史记录(例如,清除 db 表,从迁移指导中删除迁移文件) ,然后重新运行,

./management. py 模式迁移 southut ——初始化

因此,如果任何人以前这样做过,并有一些提示/建议,他们将不胜感激。

64795 次浏览

编辑-我把一个评论放在下面的顶部,因为在@andybak 后面的 > 接受的答案之前阅读它是很重要的

@ Dominique: 你关于 Manage.py 向南重置的建议很危险 并可能会破坏数据库,如果有任何第三方应用程序使用 正如下面@thnee 所指出的 如果你能编辑一下,我会非常感激的 它,并添加至少一个警告这一点,或(甚至更好)改变它 反映@hobs 方法(这种方法同样方便,但是不方便 影响其他应用程序)-谢谢!-chrisv Mar 26’13 at 9:09

接受的答复如下:

首先,南方作者的回答:

只要您注意在所有部署中同时进行,就不会有任何问题。就我个人而言,我会这么做:

    rm -r appname/migrations/
./manage.py reset south
./manage.py convert_to_south appname

(请注意,“ reset south”部分为所有应用程序清除迁移记录,因此请确保为所有应用程序运行其他两行或有选择地删除)。

最后的 convert_to_south调用进行一次新的迁移并假应用它(因为您的数据库已经有了相应的表)。在这个过程中没有必要删除所有的应用程序表。

当我需要摆脱所有这些不必要的开发迁移时,下面是我在我的 dev + 生产服务器上做的事情:

  1. 确保两边都有相同的 DB 模式
  2. 删除双方的迁移文件夹
  3. Py 在两边都重置了 South (正如文章所说) = 清除了南边的表 *
  4. 在两边都运行./manager. py 转换到南方(伪造0001迁移)
  5. 然后我可以重新开始进行迁移,并推动迁移文件夹在我的服务器上

* 除非你只想清理其中一个应用程序,如果是这样的话,你需要编辑你的 South _ history 表并且只删除关于你的应用程序的条目。

如果您只是在开发机器上工作,那么我编写了一个管理命令,它基本上完成了 Dominique 建议的任务。

Http://balzerg.blogspot.co.il/2012/09/django-app-reset-with-south.html

与南方作者的建议相反,这将不会损害其他使用南方安装的应用程序。

如果你需要有选择性地(仅仅为一个应用程序)重置花费太长时间的迁移,这个为我工作。

rm <app-dir>/migrations/*
python manage.py schemamigration <app-name> --initial
python manage.py migrate <app-name> 0001 --fake  --delete-ghost-migrations

不要忘记在其他应用程序上手动恢复任何 依赖关系,方法是将类似 depends_on = (("<other_app_name>", "0001_initial"),("<yet_another_app_name>", "0001_initial"))的行添加到 <app-dir>/migrations/0001_initial.py文件中,作为迁移类中略低于 class Migration(SchemaMigration):的第一个属性。

然后,您可以在其他环境中使用 ./manage.py migrate <app-name> --fake --delete-ghost-migrations,每个 这么回答。当然,如果您伪造删除或者伪造 migrate zero,那么您将需要通过像 这个这样的迁移手动删除任何剩余的数据库表。

一个更核心的选项是在活动部署服务器上使用 ./manage.py migrate --fake --delete-ghost-migrations,然后使用[ my ] sqldump。然后在需要迁移的、完全填充的 db 的环境中将这个转储通过管道传输到[ my ] sql 中。南方亵渎,我知道,但对我有用。

感谢瓜迪奥拉和霍布斯的回答,它帮助我解决了一个难题。 然而,这个解决方案存在一些问题,以下是我对它的看法。

如果您有任何使用 South 的 第三方应用程序,例如 django-cms(基本上所有东西都使用 South) ,那么使用 manage.py reset south就是 不是个好主意

reset south将删除您安装的所有应用程序的所有迁移历史记录。

现在考虑升级到最新版本的 django-cms,它将包含像 0009_do_something.py这样的新迁移。如果在迁移历史中没有 0001通过 0008运行迁移,South 肯定会感到困惑。

只选择性地重置 你在维持的应用程序会更好/更安全。


首先,确保您的应用程序在磁盘上的迁移和在数据库上执行的迁移之间没有任何同步。不然会头痛的。

为我的应用程序删除迁移历史记录

sql> delete from south_migrationhistory where app_name = 'my_app';

为我的应用程序删除迁移

$ rm -rf my_app/migrations/

为我的应用程序创建新的初始迁移

$ ./manage.py schemamigration --initial my_app

4. 为我的应用程序执行假的初始迁移

这将在不触及实际表的情况下将迁移插入到 south_migrationhistory中:

$ ./manage.py migrate --fake my_app

步骤3和步骤4实际上只是 manage.py convert_to_south my_app的一个更长的变体,但是在修改生产数据库这样的微妙情况下,我更喜欢这种额外的控制。

只有当你想重置所有应用程序时,才需要这样做。请在此工作之前备份所有数据库。如果有的话,还要在初始文件中记下你的 取决于

就这一次:

(1) find . -type d -name migrations -exec git rm -rf '{}' \;
(2) find . -type d -name migrations -exec rm -rf '{}' \;
(3) ./manage.py schemamigration <APP_NAME> --initial
(4) [GIT COMMIT]

在推送之前测试引导项目。然后,对于每个本地/远程计算机,应用以下命令:

(5) [GIT PULL]
(6) ./manage.py reset south
(7) ./manage.py migrate --fake

为你想要重新参与的 每个应用程序做首字母(3)。注意,重置(6)只会删除迁移历史,因此不会对库造成损害。伪造的迁移(7)会将安装的任何第三方应用的迁移历史恢复。

像 Thnee (见她的回答)一样,我们使用了一种更温和的方法来处理这里引用的南方作者(Andrew Godwin)的建议,并且我们在部署期间将我们对代码库所做的工作与我们对数据库所做的工作分离开来,因为我们需要部署是可重复的:

我们在代码中的操作:

# Remove all the migrations from the app
$ rm -fR appname/migrations
# Make the first migration (don't touch the database)
$ ./manage.py schemamigration appname --initial

一旦代码部署完毕,我们要对数据库做什么

# Fake the migration history, wiping out the rest
$ ./manage.py migrate appname --fake --delete-ghost-migrations

从应用程序文件夹中删除必要的文件

实例路径

 cd /usr/local/lib/python2.7/dist-packages/wiki/south_migrations

维基是我的应用