ChatGPT解决这个技术问题 Extra ChatGPT

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

我已经使用 South (0.7) 和 Django (1.1.2) 积累了相当多的迁移,这些迁移在我的单元测试中开始消耗相当多的时间。我想重置基线并开始一组新的迁移。我查看了 South documentation,完成了通常的 Google/Stackoverflow 搜索(例如“django south(重置或删除或删除)迁移历史”),但没有发现任何明显的东西。

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

./manage.py schemamigration southtut --initial

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

有时您需要手动将 __init__.py 添加到 appname/migrations
如何重置 1.7 中的迁移(使用内置迁移)?
@Timo:docs.djangoproject.com/en/dev/topics/migrations/… 可能是一种方法。您也可以只删除您的 migrations/ 目录并重新发布 ./manage.py makemigrations,但如果您不从新的数据库开始,就会发生不好的事情......
我认为 squashmigrations 是正确答案

C
Community

如果您需要有选择地(仅针对一个应用程序)重置耗时过长的迁移,this 对我有用。

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

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

然后,您可以按照 this SO answer 在其他环境中./manage.py migrate <app-name> --fake --delete-ghost-migrations。当然,如果您伪造删除或伪造 migrate zero,您需要手动删除任何剩余的数据库表,如 this 迁移。

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


我真正想要的是“把models.py当作福音,从那时起让我干净利落”。因此保留了从头开始设置部署或从现有部署工作的能力。
这就是这样做的。
@hobs 我在伪造新的初始迁移时得到了一个 DependsOnUnknownMigration。感谢您的评论,我知道我应该更新引用此应用程序的 depends_on 语句。这真的是这里最好的答案。谢谢! :)
A
Andy Baker

编辑-我在下面的顶部发表评论,因为在@andybak @Dominique 后面的>接受答案之前阅读它很重要:您关于manage.py reset south的建议是危险的,如果有可能会破坏数据库正如下面@thnee 所指出的,在项目中使用 south 的任何第三方应用程序。由于您的答案有很多赞成票,如果您可以对其进行编辑并至少添加一个警告,或者(甚至更好)将其更改为反映@hobs方法(这同样方便,但不影响其他应用程序) - 谢谢! – chrisv 2013 年 3 月 26 日 9:09 接受的答案如下:

首先,an answer by the South author

只要您注意同时在所有部署上执行此操作,就不会出现任何问题。就个人而言,我会这样做: rm -r appname/migrations/ ./manage.py reset south ./manage.py convert_to_south appname (请注意,“reset south”部分会清除所有应用程序的迁移记录,因此请确保您要么运行所有应用程序的其他两行或有选择地删除)。最后的 convert_to_south 调用会进行新的迁移并伪造应用它(因为您的数据库已经有相应的表)。在此过程中无需删除所有应用程序表。

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

确保我们在两边都有相同的数据库模式删除两边的每个迁移文件夹在两边运行./manage.py reset south(如帖子所说)=清除南表*在两边运行./manage.py convert_to_south双方(伪造0001迁移)然后我可以重新开始进行迁移并将迁移文件夹推送到我的服务器上

除非您只想清理其中一个应用程序,否则您需要编辑 south_history 表并仅删除有关您的应用程序的条目。


作为记录,南方作者的回应如下:只要您注意同时在所有部署上执行此操作,这应该没有任何问题。就个人而言,我会这样做: rm -r appname/migrations/ ./manage.py reset south ./manage.py convert_to_south appname (请注意,“reset south”部分会清除所有应用程序的迁移记录,因此请确保您要么运行所有应用程序的其他两行或选择性删除)。
另请注意,如果删除表,则需要 manage.py schemamigration app name --initial 而不是 convert_to_south。
从 Django 1.5 开始,“reset”管理命令消失了。相反,您需要做一些大致类似于 south.models.MigrationHistory.objects.all().delete() 的事情。
@Dominique:您关于 manage.py reset south 的建议是危险并且可能会破坏数据库如果项目中有任何使用 south 的第三方应用程序,如下面的@thnee 所指出.由于您的答案有很多赞成票,如果您可以对其进行编辑并至少添加一个警告,或者(甚至更好)将其更改为反映@hobs方法(这同样方便,但不影响其他应用程序) - 谢谢!
为什么这会受到如此高的评价?您几乎不应该完全删除您的 south_migrationhistory 表。这将完全搞砸任何您不想接触的迁移依赖的应用程序。霍布的回答是正确的。
t
thnee

感谢多米尼克瓜迪奥拉和霍布斯的回答,它帮助我解决了一个难题。但是,该解决方案存在一些问题,这是我的看法。

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

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

现在考虑升级到最新版本的 django-cms,它将包含新的迁移,如 0009_do_something.py。当您尝试在迁移历史记录中没有 00010008 的情况下尝试运行该迁移时,South 肯定会感到困惑。

仅选择性地重置您正在维护的应用程序会更好/更安全。

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

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

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

2. 删除我的应用程序的迁移

$ rm -rf my_app/migrations/

3. 为我的应用创建新的初始迁移

$ ./manage.py schemamigration --initial my_app

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

这会将迁移插入 south_migrationhistory 而不触及实际表:

$ ./manage.py migrate --fake my_app

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


我编辑了我的答案以包含对您发现的问题的修复(只是根据您的答案猜测它们),并在具有数百万行的生产数据库上对其进行了测试。
这几乎就是我们正在做的事情。如果在第 4 步使用 --delete-ghost-migrations 选项,则可以省略第 1 步。
如果您不想伪造迁移其他有待迁移的应用程序,则应在 ./manage.py migrate --fake 中明确指定应用程序名称。
@wadim因此第0步:“确保磁盘上的迁移与已在数据库上执行的迁移之间没有不同步”。
@thnee 对。可能值得一提的是,您在第 0 步中引用了所有已安装的应用程序。您知道执行第 0 步的简单方法吗?
t
tobych

就像 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

我想我只是做了同样的事情,但是手动删除数据库条目,而不是使用 --delete_ghoist-migrations。你的方法好一点。
i
idanzalz

如果您只是在开发机器上工作,我编写了一个管理命令,它几乎可以执行 Dominique 的建议。

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

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


如果与作者不同,您希望保留现有迁移(即,您希望重置应用程序以及迁移历史记录,但保留实际迁移),那么您可以试试这个:goo.gl/0ZnWm
h
hurturk

以下仅当您要重置所有应用程序时。请在该工作之前备份您的所有数据库。如果有的话,还要在初始文件中记下您的 depends_on

一次:

(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)。请注意,reset (6) 将仅删除迁移历史记录,因此对库无害。虚假迁移 (7) 将放回已安装的任何第 3 方应用程序的迁移历史记录。


A
Andrei Eremchuk

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

实例路径

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

wiki - 是我的应用程序


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅