移行システムを使用するDjango 1.8プロジェクトを開始しました。
どうやら物事が面倒になったので、移行フォルダーとテーブルをDBから消去しましたが、今は成功せずに再構築しようとしています。
3つのアプリ(3 models.py
ファイル)があり、モデルはテーブルを正確に反映しています!
私がこれまでに見つけた最良のアプローチは次のとおりです。
migrations
フォルダーを消去します。できた!Django_migrations
テーブルからすべてを削除します。できた!python manage.py makemigrations --empty <app>
を実行します。できた!python manage.py migrate --fake
を実行します。できた! (ただし、すべてのmakemigrations
コマンドの後に実行した場合にのみ機能します。新しいフィールドを追加し、makemigrations
コマンドを実行すると、次のエラーが表示されます。Django.db.utils.OperationalError: (1054, "Unknown column 'accounts_plan.max_item_size' in 'field list'")
私はこのことについて何時間も燃やしてきました。毎回移行を中断せずに作業を継続できるように、移行を初期化するにはどうすればよいですか?
なぜそんなに複雑なのですか?なぜ単純なワンライナーがありません:initiate_migrations_from_schema
?
編集:
今では物事はさらに厄介になります。 Django_migrations
テーブルを切り捨て、migrations
フォルダーをすべて削除しました。
今、python manage.py migrate --fake-initial
(DEVドキュメントで見つけたもの)を実行しようとしていますが、Djangoのすべての「内部」アプリ(認証、セッションなど)をセットアップするだけです。(1054, "Unknown column 'name' in 'Django_content_type'")
。
現在、この「列」は実際の列ではありません。 Djangoのcontenttypes
アプリで定義されている@property
です。 ISは何ですか? name
プロパティを実際の列として識別するのはなぜですか?
ついに機能するようになりましたが、その理由はわかりませんが、将来的に機能することを願っています。
多数のトライアルを行い、Djangoの開発サイトを通過した後( link )。
手順は次のとおりです(この問題が発生した場合)。
Django_migrations
テーブルを空にします:delete from Django_migrations;
migrations
フォルダーを削除します:rm -rf <app>/migrations/
python manage.py migrate --fake
python manage.py makemigrations <app>
。依存関係に注意してください(ForeignKeyのあるモデルは、親モデルの後に実行する必要があります)。python manage.py migrate --fake-initial
その後、念のため、--fake-initial
フラグなしで最後のコマンドを実行しました。
これですべてが機能し、移行システムを通常どおり使用できます。
この問題に遭遇したのは私だけではないはずです。より適切に文書化し、さらには簡素化する必要があります。
Django 1.9ユーザーの更新:
再びこのシナリオでDjango 1.9.4を使用し、ステップ5が失敗しました。
私がしなければならなかったのは、--fake-initial
を--fake
に置き換えて機能させることだけです。
私はこのシナリオに遭遇しましたが、解決するためにデータベースをドロップする必要はありませんでした。通常、アプリから移行フォルダを削除し、データベースから移行エントリを削除します。
私は一度に1つのアプリで移行を実行しようとします。アプリのいずれかが他のテーブルに依存している場合、明らかに最後に追加します。
また、私は通常、単に実行しますpython manage.py makemigrations次にちょうどpython manage.py migrate最初の移行でも、Django 1.7で正常に動作するはずです1.8.
Django ...、1.8、1.9、...
達成したいのは、既存の移行を無効にし、それらの代替を使用することです。
リリース時にコマンドを使用せずに正しく実行する方法(データベースと同僚に影響を与えないケース)。
すべてのアプリについて、その移行フォルダーを取り除きます:mv <app>/migrations/ <app>/migrationsOLD/
アプリを実行するたびに:python manage.py makemigrations <app>
。
新しい移行をそれぞれカスタマイズします。
CircularDependencyError
またはValueError: Unhandled pending operations for models
を避けるために、複雑なアプリ、またはそれらの間に複数のアプリと関連モデルがある場合:
<app>
0002_initial2.py
で2番目の空の移行を準備します(app_other::0001_initial.py
および<app>
:: 0001_initial.py
にも依存関係を置きます-で作成されたすべてのForeignKey、M2M 0001他のアプリの移行手順)
すべての順序を整える必要があります-準備のためにさらに移行が必要になる場合があります。ここで、各移行でdependencies
属性に注意してください。
初期値に注意してください-RunPython
からのmigrationsOLD
アクションをすべて確認し、必要に応じてコードを新しい初期移行にコピーしてください。
(--fake-initial
のオプション)initial=True
をすべての新しい移行クラスに追加します(追加された場合は0002も)。
replaces
属性を追加します。 (独自のカスタムsquashmigrations
など)。 <app>
からの古い移行をすべてそこに配置しますmakemigrations
ですべてを確認します。
「変更は検出されませんでした」とアサートします
migrate -l
が[x]をどこにでも表示するかどうかを確認します
同様のアサート:
[X] 0001_initial
[X] 0002_initial2(102押しつぶされた移行)
例:
古い場合:
0001_initial.py
0002_auto.py
...
0103_auto.py
準備する:
0001_initial.py
0002_initial2.py (optional but sometimes required to satisfy dependency)
最後のreplaces
に追加します(ここでは0002、0001でも可):
replaces = [(b'<app>', '0002_auto.py'), ..., (b'<app>', '0103_auto.py')]
0001_initial.pyは、古い名前と同じ名前にする必要があります。
0002_initial2.pyは新しいものですが、古い移行の代わりになるため、Djangoはそれをロード済みとして扱います。
ルーターを使用している場合、そこに問題がある可能性があります。 allow_migrate
で正しい方法で実行されている場合は、メソッドrouters.py
を確認します。戻り値を常にTrue
に設定し、問題が解決するかどうかを確認してください。
def allow_migrate(self, db, app_label, model_name=None, **hints):
return True