Django Southを使用して移行履歴をリセットするための推奨アプローチは何ですか?


153

私は、South(0.7)とDjango(1.1.2)を使用してかなりの数のマイグレーションを蓄積してきました。これらは、ユニットテストでかなりの時間を消費し始めています。ベースラインをリセットして、新しい移行のセットを開始したいと思います。私はSouthのドキュメントを確認し、通常のGoogle / Stackoverflow検索を実行しました(たとえば、「django south(リセットまたは削除または削除)移行履歴」)。明らかなものは何も見つかりませんでした。

私が考えた1つのアプローチは、Southを手動で「削除」または「クリア」して「最初からやり直す」(たとえば、dbテーブルをクリアする、migrations directorから移行ファイルを削除する)ことと、単に再実行することです。

./manage.py schemamigration southtut --initial

したがって、誰かがこれを以前に行ったことがあり、いくつかのヒント/提案があれば、彼らは大いに感謝します。


時には手動で追加__init__.pyする必要がありますappname/migrations
laike9m

2
1.7の移行を(組み込みの移行を使用して)どのようにリセットしますか?
Timo

1
@Timo:docs.djangoproject.com/en/dev/topics/migrations/…がアプローチになる可能性があります。migrations /ディレクトリを削除して再発行./manage.py makemigrationsすることもできますが、新しいdbから始めないと悪いことが起こります...
Jocelyn delalande

squashmigrationsは正しい答えだと思います
フリオ・マリンズ

回答:


121

編集-@andybakに続く>承認された回答の前にそれを読むことが重要であるため、これの上部にコメントを付けます

@Dominique:以下の@thneeで指摘されているように、manage.py reset southに関するアドバイスは危険であり、プロジェクトでsouthを使用しているサードパーティのアプリがある場合、データベースを破壊する可能性があります。あなたの回答には非常に多くの賛成票があるので、編集して少なくともこれに関する警告を追加できるか、@ hobsアプローチを反映するように(さらに良いことに)変更していただければ幸いです(これは同じくらい便利ですが、そうではありません)他のアプリに影響します)-ありがとうございます!– chrisv 2013年3月26日9:09

受け入れられた答えは以下の通りです:

まず、南部の作者による答え

すべての展開で同時にそれを行うように注意する限り、これで問題は発生しないはずです。個人的に、私はやります:

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

(「reset south」の部分はすべてのアプリの移行レコードをクリアするため、すべてのアプリに対して他の2行を実行するか、選択的に削除してください)。

convert_to_south最後の呼び出しにより、新しい移行が行われ、それが偽で適用されます(データベースに対応するテーブルが既にあるため)。プロセス中にすべてのアプリテーブルを削除する必要はありません。

これらの不要な開発者の移行をすべて取り除く必要があるときに、開発者+本番サーバーで私がやっていることは次のとおりです。

  1. 両側に同じDBスキーマがあることを確認してください
  2. 両側のすべてのマイグレーションフォルダを削除する
  3. run ./manage.py reset the south(post)両側で=南テーブルをクリア*
  4. 両側で./manage.py convert_to_southを実行します(0001の移行に似ています
  5. その後、移行を再開してサーバーに移行フォルダをプッシュすることができます

* 1つのアプリのみをクリーンアップする場合を除き、そうする場合は、south_historyテーブルを編集して、アプリに関するエントリのみを削除する必要があります。


2
参考までに、Southの作成者の対応は次のとおりです。すべての展開で同時に実行するように注意する限り、これに問題はありません。個人的には、次のようにします:rm -r appname / migrations / ./manage.py reset south ./manage.py convert_to_south appname(「reset south」の部分はすべてのアプリの移行レコードをクリアするので、必ず実行するか、他の2行はすべてのアプリに適用されるか、選択的に削除されます)。
Adriaan Tijsseling

2
テーブルを削除する場合manage.py schemamigration app name --initialは、convert_to_southの代わりに必要になることにも注意してください。
Adriaan Tijsseling

7
Django 1.5以降、「リセット」管理コマンドはなくなりました。代わりに、おおよそのようなことをしたいと思うでしょうsouth.models.MigrationHistory.objects.all().delete()
Andrew B.

13
@Dominique:あなたのアドバイスについては、manage.py reset southある危険データベースを破壊することがあり、以下の@thneeによって尖ったアウトとして、プロジェクトに南使用して任意のサードパーティ製のアプリケーションがある場合。あなたの回答には非常に多くの賛成票があるので、編集して少なくともこれに関する警告を追加できるか、@ hobsのアプローチを反映するように変更してください(これは同じように便利ですが、そうではありません)他のアプリに影響します)-ありがとうございます!
chrisv 2013年

3
なぜこれが非常に賛成されたのですか?south_migrationhistoryテーブルをほとんど完全に削除しないでください。それはあなたが触れたくない移行で依存するアプリを完全に台無しにするでしょう。ホブの答えは正しいものです。
セリン

188

あなたが選択する必要がある場合は時間がかかりすぎているリセットマイグレーション(ただ1つのアプリのために)、これは私のために働きました。

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このSOの回答に従って、他の環境で行うことができます。もちろん、削除を偽造したり、偽造したりするmigrate zero場合は、このような移行で残っているdbテーブルを手動で削除する必要があります。

より核となるオプションは./manage.py migrate --fake --delete-ghost-migrations、ライブ展開サーバーで[my] sqldumpを実行することです。次に、そのダンプを、完全に移植された移行済みのdbが必要な環境の[my] sqlにパイプします。南の聖職者、私は知っているが、私のために働いた。


2
私が本当に欲しがっているのは、「models.pyを福音として受け取り、その時点から私をクリーンアップする」ことです。したがって、デプロイメントを最初からセットアップする機能、または既存のデプロイメントから作業する機能を保持します。
ブライス2014年

1
それがこれです。
ホブ2014年

2
@hobs私はDependsOnUnknownMigrationしばらくして、新しい初期移行を偽装していた。あなたのコメントのおかげで、私はdepends_onそれがこのアプリについて言及しているところはどこでもステートメントを更新すべきだと理解できました。これは本当にここでの最良の答えです。ありがとう!:)
マヌ14

55

Dominique Guardiolaとhobsの回答のおかげで、難しい問題の解決に役立ちました。しかし、解決策にはいくつかの問題があります。これが私の見解です。

たとえば、Southを使用するサードパーティのアプリがある場合(基本的にはすべてSouthを使用する)使用manage.py reset southお勧めできませんdjango-cms

reset south インストールしたすべてのアプリの移行履歴をすべて削除します。

次に、の最新バージョンにアップグレードすると、のdjango-cmsような新しいマイグレーションが含まれるようになり0009_do_something.pyます。あなたがなくても、その移行を実行しようとすると、南は確かに混同され00010008、移行の歴史の中で。

維持ているアプリのみを選択的にリセットする方がはるかに優れており、安全です。


まず、ディスク上の移行とデータベースで実行された移行の間でアプリの同期が取れていないことを確認してください。さもなければ頭痛がするでしょう。

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が、実稼働データベースの変更などのデリケートな状況では、追加の制御を優先します。


2
私はあなたが見つけた問題の修正を組み込むために私の回答を編集し(あなたの回答に基づいてそれらを推測するだけ)、何百万もの行がある本番データベースでテストしました。
ホブ2013

2
これはほとんど私たちがやっていることです。あなたがステップ4で、--delete-ゴースト移行オプションを使用する場合は、手順1アウト残すことができます
tobych

./manage.py migrate --fake移行が保留されている他のアプリを偽の移行にしたくない場合は、アプリ名を明示的に指定する必要があります。
ワディム2013年

2
@wadimしたがって、ステップ0:「ディスク上のマイグレーションと、データベース上で実行されたマイグレーションとの間に非同期がないことを確認してください」。
2013年

@thneeそうです。ステップ0でインストールされたすべてのアプリを参照していることは、おそらく言及する価値があります。ただし、ステップ0を実行する簡単な方法を知っていますか?
ワディム2013年

7

thnee(彼女の回答を参照)のように、ここでは他の場所で引用されているSouthの作者(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を使用するのではなく、手動でデータベースエントリを削除します。あなたの方法は少しいいです。
wobbily_col 14

1

開発マシンで作業しているだけの場合は、Dominiqueの提案とほぼ同じことを行う管理コマンドを作成しました。

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

南部の作者の提案とは対照的に、これは南部を使用してインストールされている他のアプリを害しません。


そして、作成者とは異なり、既存の移行を維持したい場合(つまり、アプリと移行履歴をリセットし、実際の移行は維持したい場合)、これを試すことができます:goo.gl/0ZnWm
mgalgs

1

以下は、すべてのアプリをリセットする場合のみです。その作業の前に、すべてのデータベースをバックアップしてください。また、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)を実行します。リセット(6)はマイグレーション履歴のみを削除するため、ライブラリに害はないことに注意してください。偽の移行(7)は、インストールされているすべてのサードパーティアプリの移行履歴を元に戻します。


0

アプリフォルダーから必要なファイルを削除する

インスタンスパス

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

wiki-私のアプリです

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.