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

时间:2022-04-16 19:57:36

I've accumulated quite a few migrations using South (0.7) and Django (1.1.2) which are starting to consume quite a bit of time in my unit tests. I would like to reset the baseline and start a fresh set of migrations. I've reviewed the South documentation, done the usual Google/* searching (e.g. "django south (reset OR delete OR remove) migration history") and haven't found anything obvious.

我已经使用South(0.7)和Django(1.1.2)积累了相当多的迁移,这在我的单元测试中开始消耗大量时间。我想重新设置基线并开始一组新的迁移。我检查了南部文档,做了通常的谷歌/*搜索(例如。“django south(重置或删除或删除)迁移历史”)并没有发现任何明显的变化。

One approach I've contemplated would involve "starting over" by "removing" South or "clearing" the history manually (e.g. clear the db table, remove migration files from the migrations director) and just re-run,

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

./manage.py schemamigration southtut --initial

/管理。py schemamigration southtut——最初的

So, if anyone has done this before and has some tips/suggestions they would be greatly appreciated.

因此,如果有人以前做过,并有一些建议,他们将非常感激。

7 个解决方案

#1


121  

EDIT - I'm putting a comment below at the top of this as it's important to read it before the > accepted answer that follows @andybak

编辑——我在下面加上一条评论,因为在>接受@andybak后面的答案之前阅读它是很重要的

@Dominique: Your advice regarding manage.py reset south is dangerous and may destroy the database if there are any third party apps using south in the project, as pointed out by @thnee below. Since your answer has so many upvotes I'd really appreciate it if you could edit it and add at least a warning about this, or (even better) change it to reflect @hobs approach (which is just as convenient, but doesn't affect other apps) - thanks! – chrisv Mar 26 '13 at 9:09

多米尼克:关于管理的建议。如果有任何第三方应用程序在项目中使用南方,如@thnee所指出的,py重置南方是危险的,可能会破坏数据库。既然你的答案有这么多的支持,我真的很感激你能编辑它,并且至少添加一个警告,或者(甚至更好)改变它来反映@hobs方法(这很方便,但不会影响其他应用)-谢谢!- chrisv 3月26日9点09分

Accepted answer follows below:

接受回答如下所示:

First, an answer by the South author:

首先,南方作者的回答是:

As long as you take care to do it on all deployments simultaneously, there shouldn't be any problem with this. Personally, I'd do:

只要您同时在所有部署上执行,就不会有任何问题。就我个人而言,我做的事:

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

(Notice that the “reset south” part clears migration records for ALL apps, so make sure you either run the other two lines for all apps or delete selectively).

(请注意,“reset south”部分清除了所有应用程序的迁移记录,所以请确保您要么运行所有应用程序的其他两行,要么有选择地删除)。

The convert_to_south call at the end makes a new migration and fake-applies it (since your database already has the corresponding tables). There's no need to drop all the app tables during the process.

最后的convert_to_south调用进行新的迁移并应用它(因为您的数据库已经拥有相应的表)。在此过程中不需要删除所有的应用程序表。

Here's what I'm doing on my dev + production server when I need to get rid of all these unneeded dev migrations:

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

  1. Make sure we have the same DB schema on both sides
  2. 确保我们在两边都有相同的DB模式
  3. delete every migrations folder on both sides
  4. 删除双方的每个迁移文件夹。
  5. run ./manage.py reset south (as the post says) on both sides = clears the south table *
  6. 运行。/管理。py重新设置南下(如post所说),两边=清除南下表*
  7. run ./manage.py convert_to_south on both sides (faking 0001 migration)
  8. 运行。/管理。两侧均为py convert_to_south(假装0001迁移)
  9. then I can re-start to make migrations and push the migrations folders on my server
  10. 然后我可以重新开始进行迁移并在我的服务器上按下迁移文件夹

* except if you want to clean only one app among others, if so you'll need to edit your south_history table and delete only the entries about your app.

*除非你想只清理一个应用程序,否则你需要编辑你的south_history表,只删除关于你的应用程序的条目。

#2


188  

If you need to selectively (for just one app) reset migrations that are taking too long, this worked for me.

如果您需要有选择地(只针对一个应用程序)重置耗时太长的迁移,这对我来说是有效的。

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

Don't forget to manually restore any dependencies on other apps by adding lines like depends_on = (("<other_app_name>", "0001_initial"),("<yet_another_app_name>", "0001_initial")) to your <app-dir>/migrations/0001_initial.py file, as the first attribute in your migration class just below class Migration(SchemaMigration):.

不要忘记通过将depends_on =(“ ”、“0001_initial”)、(“ ”、“0001_initial”)等行添加到< app-> /migrations/0001_initial来手动恢复对其他应用的依赖。py文件,作为迁移类中位于类迁移(SchemaMigration)下面的第一个属性:。

You can then ./manage.py migrate <app-name> --fake --delete-ghost-migrations on other environments, per this SO answer. Of course if you fake the delete or fake the migrate zero you'll need to manually delete any left-over db tables with a migration like this.

然后您可以。/管理。py迁移 ——伪——删除-重影-迁移到其他环境中,根据这个SO答案。当然,如果您伪造删除或伪造迁移零,您将需要像这样手工删除任何遗留的db表。

A more nuclear option is to ./manage.py migrate --fake --delete-ghost-migrations on the live deployment server followed by a [my]sqldump. Then pipe that dump into [my]sql on the environments where you need the migrated, fully-populated db. South sacrilege, I know, but worked for me.

一个更核心的选择是去管理。py迁移——在live部署服务器上的假的-删除-ghost-迁移,然后是一个[我的]sqldump。然后在需要迁移的、完全填充的db的环境中将该转储导入[my]sql。南渎神,我知道,但为我工作。

#3


54  

Thanks to the answers by Dominique Guardiola and hobs, it helped me solve a hard problem. However there are a couple of issues with the solution, here is my take on it.

多亏了Dominique Guardiola和hobs的回答,它帮助我解决了一个难题。然而,这个解决方案存在一些问题,以下是我对此的看法。

Using manage.py reset south is not a good idea if you have any third party apps that uses South, for example django-cms (basically everything uses South).

使用管理。如果你有使用south的第三方应用,比如django-cms(基本上所有应用都使用south), py reset south不是一个好主意。

reset south will delete all migration history for all apps that you have installed.

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

Now consider that you upgrade to the latest version of django-cms, it will contain new migrations like 0009_do_something.py. South will surely be confused when you try to run that migration without having 0001 through 0008 in the migration history.

现在考虑到升级到最新版本的django-cms,它将包含新的迁移,比如0009_do_something.py。当您试图在迁移历史上没有0001到0008的迁移时,南方肯定会感到困惑。

It is much better/safer to selectively reset only the apps that you are maintaining.

有选择地重新设置你正在维护的应用程序会更好/更安全。


First of all, make sure that your apps don't have any desync between migrations on disk, and migrations that have been executed on the database. Otherwise there will be headache.

首先,确保您的应用程序在磁盘上的迁移和数据库上执行的迁移之间没有任何desync。否则就会头疼。

1. Delete migration history for my apps

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

2. Delete migrations for my apps

$ rm -rf my_app/migrations/

3. Create new initial migrations for my apps

$ ./manage.py schemamigration --initial my_app

4. Fake execute the initial migrations for my apps

This inserts the migrations into south_migrationhistory without touching actual tables:

这将迁移插入到south_migrationhistory,而不涉及实际的表:

$ ./manage.py migrate --fake my_app

Step 3 and 4 is actually just a longer variant of manage.py convert_to_south my_app, but I prefer that extra control, in such delicate situation as modifying the production database.

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

#4


7  

Like thnee (see her answer), we're using a gentler approach to the South author's (Andrew Godwin) suggestion quoted elsewhere here, and we're separating what we do with the code base from what we do to the database, during deployment, because we need the deployments to be repeatable:

就像thnee(见她的答案)一样,我们使用一种更温和的方法来处理本文其他地方引用的South author (Andrew Godwin)的建议,我们将代码库的处理与数据库的部署分离开来,因为在部署过程中,我们需要可重复的部署:

What we do in the code:

我们在代码中所做的:

# 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

What we do to the database once that code is deployed

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

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

#5


1  

If you are just working on the dev machine, I wrote a management command that does pretty much what Dominique suggested.

如果您只是在开发机器上工作,那么我编写了一个管理命令,它所做的工作与Dominique建议的差不多。

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

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

In contrast of the south author suggestion, this will NOT HARM other installed apps using south.

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

#6


0  

Following is only if you want to reset all apps. Please backup your all databases prior to that work. Also note down your depends_on in initial files if there are any.

只有当你想重新设置所有的应用程序的时候。请在工作之前备份所有的数据库。如果初始文件中有依赖项,也要记录下来。

For once:

这一次:

(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]

Test bootstrapping your project before push. Then, for each local/remote machine, apply following:

在push之前测试引导项目。然后,对于每台本地/远程机器,应用如下:

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

Do initial (3) for each app you want to re-involve. Note that, reset (6) will delete only migration history, therefore not harmful to libraries. Fake migrations (7) will put back migration history of any 3rd party apps installed.

对你想要重新参与的每个应用都进行初始化(3)。注意,reset(6)将只删除迁移历史,因此不会对库有害。假迁移(7)会使安装的任何第三方应用程序的迁移历史倒退。

#7


0  

delete necessary file from app folder

从app文件夹中删除必要的文件

instance path

实例路径

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

wiki -is my app

wiki是我的程序

#1


121  

EDIT - I'm putting a comment below at the top of this as it's important to read it before the > accepted answer that follows @andybak

编辑——我在下面加上一条评论,因为在>接受@andybak后面的答案之前阅读它是很重要的

@Dominique: Your advice regarding manage.py reset south is dangerous and may destroy the database if there are any third party apps using south in the project, as pointed out by @thnee below. Since your answer has so many upvotes I'd really appreciate it if you could edit it and add at least a warning about this, or (even better) change it to reflect @hobs approach (which is just as convenient, but doesn't affect other apps) - thanks! – chrisv Mar 26 '13 at 9:09

多米尼克:关于管理的建议。如果有任何第三方应用程序在项目中使用南方,如@thnee所指出的,py重置南方是危险的,可能会破坏数据库。既然你的答案有这么多的支持,我真的很感激你能编辑它,并且至少添加一个警告,或者(甚至更好)改变它来反映@hobs方法(这很方便,但不会影响其他应用)-谢谢!- chrisv 3月26日9点09分

Accepted answer follows below:

接受回答如下所示:

First, an answer by the South author:

首先,南方作者的回答是:

As long as you take care to do it on all deployments simultaneously, there shouldn't be any problem with this. Personally, I'd do:

只要您同时在所有部署上执行,就不会有任何问题。就我个人而言,我做的事:

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

(Notice that the “reset south” part clears migration records for ALL apps, so make sure you either run the other two lines for all apps or delete selectively).

(请注意,“reset south”部分清除了所有应用程序的迁移记录,所以请确保您要么运行所有应用程序的其他两行,要么有选择地删除)。

The convert_to_south call at the end makes a new migration and fake-applies it (since your database already has the corresponding tables). There's no need to drop all the app tables during the process.

最后的convert_to_south调用进行新的迁移并应用它(因为您的数据库已经拥有相应的表)。在此过程中不需要删除所有的应用程序表。

Here's what I'm doing on my dev + production server when I need to get rid of all these unneeded dev migrations:

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

  1. Make sure we have the same DB schema on both sides
  2. 确保我们在两边都有相同的DB模式
  3. delete every migrations folder on both sides
  4. 删除双方的每个迁移文件夹。
  5. run ./manage.py reset south (as the post says) on both sides = clears the south table *
  6. 运行。/管理。py重新设置南下(如post所说),两边=清除南下表*
  7. run ./manage.py convert_to_south on both sides (faking 0001 migration)
  8. 运行。/管理。两侧均为py convert_to_south(假装0001迁移)
  9. then I can re-start to make migrations and push the migrations folders on my server
  10. 然后我可以重新开始进行迁移并在我的服务器上按下迁移文件夹

* except if you want to clean only one app among others, if so you'll need to edit your south_history table and delete only the entries about your app.

*除非你想只清理一个应用程序,否则你需要编辑你的south_history表,只删除关于你的应用程序的条目。

#2


188  

If you need to selectively (for just one app) reset migrations that are taking too long, this worked for me.

如果您需要有选择地(只针对一个应用程序)重置耗时太长的迁移,这对我来说是有效的。

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

Don't forget to manually restore any dependencies on other apps by adding lines like depends_on = (("<other_app_name>", "0001_initial"),("<yet_another_app_name>", "0001_initial")) to your <app-dir>/migrations/0001_initial.py file, as the first attribute in your migration class just below class Migration(SchemaMigration):.

不要忘记通过将depends_on =(“ ”、“0001_initial”)、(“ ”、“0001_initial”)等行添加到< app-> /migrations/0001_initial来手动恢复对其他应用的依赖。py文件,作为迁移类中位于类迁移(SchemaMigration)下面的第一个属性:。

You can then ./manage.py migrate <app-name> --fake --delete-ghost-migrations on other environments, per this SO answer. Of course if you fake the delete or fake the migrate zero you'll need to manually delete any left-over db tables with a migration like this.

然后您可以。/管理。py迁移 ——伪——删除-重影-迁移到其他环境中,根据这个SO答案。当然,如果您伪造删除或伪造迁移零,您将需要像这样手工删除任何遗留的db表。

A more nuclear option is to ./manage.py migrate --fake --delete-ghost-migrations on the live deployment server followed by a [my]sqldump. Then pipe that dump into [my]sql on the environments where you need the migrated, fully-populated db. South sacrilege, I know, but worked for me.

一个更核心的选择是去管理。py迁移——在live部署服务器上的假的-删除-ghost-迁移,然后是一个[我的]sqldump。然后在需要迁移的、完全填充的db的环境中将该转储导入[my]sql。南渎神,我知道,但为我工作。

#3


54  

Thanks to the answers by Dominique Guardiola and hobs, it helped me solve a hard problem. However there are a couple of issues with the solution, here is my take on it.

多亏了Dominique Guardiola和hobs的回答,它帮助我解决了一个难题。然而,这个解决方案存在一些问题,以下是我对此的看法。

Using manage.py reset south is not a good idea if you have any third party apps that uses South, for example django-cms (basically everything uses South).

使用管理。如果你有使用south的第三方应用,比如django-cms(基本上所有应用都使用south), py reset south不是一个好主意。

reset south will delete all migration history for all apps that you have installed.

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

Now consider that you upgrade to the latest version of django-cms, it will contain new migrations like 0009_do_something.py. South will surely be confused when you try to run that migration without having 0001 through 0008 in the migration history.

现在考虑到升级到最新版本的django-cms,它将包含新的迁移,比如0009_do_something.py。当您试图在迁移历史上没有0001到0008的迁移时,南方肯定会感到困惑。

It is much better/safer to selectively reset only the apps that you are maintaining.

有选择地重新设置你正在维护的应用程序会更好/更安全。


First of all, make sure that your apps don't have any desync between migrations on disk, and migrations that have been executed on the database. Otherwise there will be headache.

首先,确保您的应用程序在磁盘上的迁移和数据库上执行的迁移之间没有任何desync。否则就会头疼。

1. Delete migration history for my apps

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

2. Delete migrations for my apps

$ rm -rf my_app/migrations/

3. Create new initial migrations for my apps

$ ./manage.py schemamigration --initial my_app

4. Fake execute the initial migrations for my apps

This inserts the migrations into south_migrationhistory without touching actual tables:

这将迁移插入到south_migrationhistory,而不涉及实际的表:

$ ./manage.py migrate --fake my_app

Step 3 and 4 is actually just a longer variant of manage.py convert_to_south my_app, but I prefer that extra control, in such delicate situation as modifying the production database.

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

#4


7  

Like thnee (see her answer), we're using a gentler approach to the South author's (Andrew Godwin) suggestion quoted elsewhere here, and we're separating what we do with the code base from what we do to the database, during deployment, because we need the deployments to be repeatable:

就像thnee(见她的答案)一样,我们使用一种更温和的方法来处理本文其他地方引用的South author (Andrew Godwin)的建议,我们将代码库的处理与数据库的部署分离开来,因为在部署过程中,我们需要可重复的部署:

What we do in the code:

我们在代码中所做的:

# 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

What we do to the database once that code is deployed

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

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

#5


1  

If you are just working on the dev machine, I wrote a management command that does pretty much what Dominique suggested.

如果您只是在开发机器上工作,那么我编写了一个管理命令,它所做的工作与Dominique建议的差不多。

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

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

In contrast of the south author suggestion, this will NOT HARM other installed apps using south.

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

#6


0  

Following is only if you want to reset all apps. Please backup your all databases prior to that work. Also note down your depends_on in initial files if there are any.

只有当你想重新设置所有的应用程序的时候。请在工作之前备份所有的数据库。如果初始文件中有依赖项,也要记录下来。

For once:

这一次:

(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]

Test bootstrapping your project before push. Then, for each local/remote machine, apply following:

在push之前测试引导项目。然后,对于每台本地/远程机器,应用如下:

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

Do initial (3) for each app you want to re-involve. Note that, reset (6) will delete only migration history, therefore not harmful to libraries. Fake migrations (7) will put back migration history of any 3rd party apps installed.

对你想要重新参与的每个应用都进行初始化(3)。注意,reset(6)将只删除迁移历史,因此不会对库有害。假迁移(7)会使安装的任何第三方应用程序的迁移历史倒退。

#7


0  

delete necessary file from app folder

从app文件夹中删除必要的文件

instance path

实例路径

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

wiki -is my app

wiki是我的程序