回答:
以前の移行に移行することで元に戻すことができます。
たとえば、最後の2つの移行が次の場合:
0010_previous_migration
0011_migration_to_revert
それからあなたはそうするでしょう:
./manage.py migrate my_app 0010_previous_migration
その後、移行を削除できます0011_migration_to_revert
。
Django 1.8+を使用している場合は、すべての移行の名前を
./manage.py showmigrations my_app
アプリのすべての移行を元に戻すには、次を実行します。
./manage.py migrate my_app zero
'0010_previous_migration'
、ではありませんが、なぜそのような動作が見られるのかわかりません。
Alasdairの答えは基本をカバーしています
./manage.py showmigrations
migrate
アプリ名と移行名を使用するただし、すべての移行を元に戻すことができるわけではないことを指摘しておく必要があります。これは、Djangoに反転を実行するルールがない場合に発生します。によって自動的に移行されたほとんどの変更では./manage.py makemigrations
、元に戻すことができます。ただし、次の例で説明するように、カスタムスクリプトには、フォワードとリバースの両方を記述する必要があります。
https://docs.djangoproject.com/en/1.9/ref/migration-operations/
RunPython
操作があった場合は、論理的に厳密な反転スクリプトを記述せずに移行をバックアウトしたいだけかもしれません。次のドキュメント(リンクの上)の例にすばやくハックすると、これが可能になり、データベースを元に戻した後も、移行が適用された後と同じ状態にデータベースが残ります。
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
def forwards_func(apps, schema_editor):
# We get the model from the versioned app registry;
# if we directly import it, it'll be the wrong version
Country = apps.get_model("myapp", "Country")
db_alias = schema_editor.connection.alias
Country.objects.using(db_alias).bulk_create([
Country(name="USA", code="us"),
Country(name="France", code="fr"),
])
class Migration(migrations.Migration):
dependencies = []
operations = [
migrations.RunPython(forwards_func, lambda apps, schema_editor: None),
]
これはDjango 1.8、1.9で動作します
更新:これを書いてのより良い方法は、置き換えることであろうlambda apps, schema_editor: None
とmigrations.RunPython.noop
上記のスニペットで。これらはどちらも機能的には同じです。(コメントへのクレジット)
RunPython.noop
インラインラムダまたはequivelentの代わりに:docs.djangoproject.com/en/1.8/ref/migration-operations/...
migrations.RunPython(forwards_func, migrations.RunPython.noop)
。機能的に確認する必要があります。これは、回答または編集としていつか追加されるはずです。
上記の解決策は実際にはユースケースをカバーしていないため、これが私の解決策ですRunPython
。
ORMを介してテーブルにアクセスできます
from django.db.migrations.recorder import MigrationRecorder
>>> MigrationRecorder.Migration.objects.all()
>>> MigrationRecorder.Migration.objects.latest('id')
Out[5]: <Migration: Migration 0050_auto_20170603_1814 for model>
>>> MigrationRecorder.Migration.objects.latest('id').delete()
Out[4]: (1, {u'migrations.Migration': 1})
したがって、テーブルにクエリを実行して、自分に関連するエントリを削除できます。この方法で、詳細を変更できます。RynPython
移行あなたも/変更/追加、削除されたデータの世話をする必要があります。上記の例は、Djang ORMを介してテーブルにアクセスする方法のみを表示しています。
django.db.utils.ProgrammingError: relation "<relation name>" already exists
ので、私が作ったmigrate --fake
間違っている、私は戻ってみましたので、私は持っpsycopg2.ProgrammingError: relation "<other <relation name>" does not exist
THANKS
もう1つのことは、手動で作成したテーブルを削除することです。
それとともに、その特定の移行ファイルを削除する必要があります。また、その特定の移行に関連するdjango-migrationsテーブルの特定のエントリ(おそらく、最後のエントリ)を削除する必要があります。
私はこれを1.9.1で行いました(作成された最後または最新のマイグレーションを削除するため):
rm <appname>/migrations/<migration #>*
例: rm myapp/migrations/0011*
データベースにログインし、このSQL(この例ではpostgres)を実行しました
delete from django_migrations where name like '0011%';
その後、削除したばかりの移行番号(この場合は11)から始まる新しい移行を作成することができました。
この回答は、Alasdairによるトップの回答が役に立たない場合の同様のケースです。(たとえば、不要な移行が新しい移行のたびにすぐに再び作成される場合、または元に戻せない大きな移行の場合、またはテーブルが手動で削除された場合)。
...新しい移行を作成せずに、移行を削除しますか?
TL; DR:モデルを修正した後、最後に元に戻された(混乱した)マイグレーションをいくつか削除し、新しいマイグレーションを作成できます。他の方法を使用して、migrateコマンドでテーブルを作成しないように構成することもできます。最後の移行は、現在のモデルと一致するように作成する必要があります。
ケース誰もが存在しなければならないモデルのテーブルを作成したくない理由:
A)そのようなテーブルは、どのマシンにもどの条件にもないデータベースに存在してはなりません。
class Meta: abstract = True
B)テーブルが他の何かによって、または特別な方法で手動で作成されることはほとんどありません。
class Meta: managed = False
C)テーブルは一部のマシンでのみ使用されます(開発中など)。
class Meta: managed = some_switch
。D)プロジェクトは複数のデータベースを使用しますsettings.DATABASES
allow_migrate
作成します。移行はすべてのケースA)、B)、C)、D)でDjango 1.9+を使用して作成されます(Django 1.8を使用するケースB、C、Dのみ)。ただし、適切な場合にのみデータベースに適用されます。必要です。Django 1.8以降、テストを実行するには移行が必要です。Django 1.9以降でmanaged = Falseが設定されているモデルでも、移行によって関連する完全な現在の状態が記録されます。これにより、管理対象/非管理対象モデル間にForeignKeyを作成したり、後でモデルをmanaged = Trueにしたりできます。(この質問はDjango 1.8の時点で書かれています。ここにあるすべては1.8から現在の2.2までのバージョンで有効です。)
最後の移行が簡単に元に戻せない場合は、データベースのバックアップ後に慎重に偽の元に戻し ./manage.py migrate --fake my_app 0010_previous_migration
、テーブルを手動で削除することができます。
必要に応じて、固定モデルから固定マイグレーションを作成し、データベース構造を変更せずにそれを適用します./manage.py migrate --fake my_app 0011_fixed_migration
。
移行を元に戻すときに問題が発生し、なんらかの方法で問題が発生した場合は、移行を実行できますfake
。
./manage.py migrate <name> --ignore-ghost-migrations --merge --fake
ジャンゴバージョン<1.7これはにエントリが作成されますsouth_migrationhistory
テーブルを、あなたはそのエントリを削除する必要があります。
これで、移行を簡単に元に戻すことができます。
PS:私は長い間立ち往生していて、偽の移行を行っていましたが、元に戻すと助けになりました。