回答:
Django移行ドキュメントからの引用:
各アプリの移行ファイルは、そのアプリ内の「migrations」ディレクトリにあり、そのコードベースにコミットされ、その一部として配布されるように設計されています。開発マシンで一度作成してから、同僚のマシン、ステージングマシン、そして最終的には本番マシンで同じ移行を実行する必要があります。
このプロセスに従えば、移行ファイルでマージの競合が発生することはありません。
バージョン管理ブランチをマージする場合、同じ親の移行に基づいて複数の移行がある状況が発生する可能性があります。たとえば、異なる開発者が移行を同時に導入した場合などです。この状況を解決する1つの方法は、_merge_migration_を導入することです。多くの場合、これはコマンドで自動的に行うことができます
./manage.py makemigrations --merge
現在のすべてのヘッドマイグレーションに依存する新しいマイグレーションが導入されます。もちろん、これはヘッドの移行間に競合がない場合にのみ機能します。その場合、問題を手動で解決する必要があります。
ここで、バージョン管理への移行をコミットすべきではないとの提案があったため、実際にそうする必要がある理由を詳しく説明します。
まず、本番システムに適用された移行の記録が必要です。変更を本番環境にデプロイし、データベースを移行する場合は、現在の状態の説明が必要です。各本番データベースに適用される移行の個別のバックアップを作成できますが、これは不必要に面倒です。
次に、移行には、カスタムの手書きコードが含まれていることがよくあります。でそれらを自動的に生成できるとは限りません./manage.py makemigrations
。
3番目に、移行はコードレビューに含まれるべきです。それらは本番システムへの重要な変更であり、それらでうまくいかないことがたくさんあります。
つまり、本番データに関心がある場合は、バージョン管理への移行を確認してください。
以下のプロセスに従ってください。
makemigrations
ローカルで実行でき、これにより移行ファイルが作成されます。この新しい移行ファイルをリポジトリにコミットします。
私の意見ではmakemigrations
、本番環境で実行するべきではありません。migrate
本番環境で実行すると、ローカルからコミットした移行ファイルから移行が適用されます。これにより、すべての競合を回避できます。
IN LOCAL ENV、移行ファイルを作成するには、
python manage.py makemigrations
python manage.py migrate
次に、以下のような、新しく作成されたファイルをコミットします。
git add app/migrations/...
git commit -m 'add migration files' app/migrations/...
本番環境では、以下のコマンドのみを実行します。
python manage.py migrate
migrate
、絶対にしないでくださいmakemigrations
。そのことを考えたことはありません。
2018年のドキュメント、Django 2.0からの引用。(2つの別々のコマンド= makemigrations
およびmigrate
)
移行を作成して適用するための個別のコマンドがあるのは、バージョン管理システムへの移行をコミットして、アプリに同梱するためです。開発を容易にするだけでなく、他の開発者や本番環境でも使用できます。
TL; DR:移行のコミット、移行の競合の解決、gitワークフローの調整。
競合を無視する代わりに、gitワークフローを調整する必要があるように感じます。
理想的には、すべての新機能は別のブランチで開発され、プルリクエストでマージされます。
競合がある場合、PRをマージすることはできません。そのため、移行を含め、機能をマージする必要がある人は競合を解決する必要があります。これには、異なるチーム間の調整が必要になる場合があります。
ただし、移行ファイルをコミットすることは重要です。競合が発生した場合、Djangoはそれらの競合を解決するのに役立つかもしれません ;)
どうにかしてマイグレーションを編集しない限り、なぜ競合が発生するのか想像できませんか?これは通常はうまく終了しません。誰かがいくつかの中間コミットを見逃した場合、正しいバージョンからアップグレードされず、データベースのコピーが破損します。
私が従うプロセスは非常に単純です。アプリのモデルを変更するたびに、移行もコミットしますが、移行は変更されません。モデルに別のものが必要な場合は、モデルを変更してコミットします。変更に伴う新しい移行。
グリーンフィールドプロジェクトでは、移行を削除して、リリース時に0001_移行でゼロからやり直すことができますが、本番用のコードがある場合はできません(移行を1つにまとめることはできます)。
通常使用される解決策は、マスターにマージする前に、開発者がリモートの変更をプルする必要があることです。移行バージョンに矛盾がある場合、彼はローカルの移行(リモートの移行は他の開発者によって実行されており、場合によっては本稼働中)の名前をN + 1に変更する必要があります。
開発中は、マイグレーションをコミットしないだけでも問題ない場合があります(ただし、無視は追加しないでadd
ください)。ただし、本番環境に移行したら、スキーマをモデルの変更と同期させるために必要になります。
次に、ファイルを編集dependencies
し、を最新のリモートバージョンに変更する必要があります。
これは、Djangoの移行や他の同様のアプリ(sqlalchemy + alembic、RoRなど)で機能します。
開発、ステージング、本番環境用に個別のDBがある場合は、移行を無視します。開発者向け。目的ローカルのsqlite DBを使用して、ローカルで移行を試すことができます。さらに4つのブランチを作成することをお勧めします。
マスター-移行せずに新鮮なコードをクリーンアップします。誰もこのブランチに接続されていません。コードレビューのみに使用
開発-毎日の開発。プッシュ/プルが受け入れられました。各開発者はsqlite DBに取り組んでいます
Cloud_DEV_env-リモートのクラウド/サーバーDEV環境。プルのみ。マシン上でローカルに移行を維持します。これは、Devデータベースのコードのデプロイとリモート移行に使用されます
Cloud_STAG_env-リモートクラウド/サーバーSTAG環境。プルのみ。マシンでローカルに移行を維持します。これは、Stagデータベースのコードのデプロイメントとリモート移行に使用されます
Cloud_PROD_env-リモートのクラウド/サーバーDEV環境。プルのみ。マシン上でローカルに移行を維持します。これは、Prodデータベースのコードのデプロイメントとリモート移行に使用されます
注:2、3、4-移行はリポジトリに保持できますが、プルリクエストのマージには厳密なルールが必要であるため、展開を担当する人物を見つけることにしました。 -er。モデルに変更があるたびに、リモートDBの移行を維持します。
短い答え
私は、レポジトリのマイグレーションを除外することを提案します。コードをマージした後、実行するだけで./manage.py makemigrations
準備完了です。
長い答え 私は、マイグレーションファイルをリポジトリに置くべきではないと思います。他の人の開発環境や他の製品やステージ環境での移行状態を台無しにします。(例については、Sugar Tangのコメントを参照してください)。
私の見解では、Djangoの移行の目的は、以前のモデルの状態と新しいモデルの状態の間のギャップを見つけ、そのギャップをシリアル化することです。コードのマージ後にモデルが変更された場合は、簡単makemigrations
にギャップを見つけることができます。他の移行を自動的かつバグなく達成できるのに、手動で慎重に他の移行をマージしたいのはなぜですか?Djangoのドキュメントによれば、
それら*(マイグレーション)*は、ほとんどが自動になるように設計されています
; そのまま保管してください。移行を手動でマージするには、他の人が何を変更したか、および変更の依存関係を完全に理解する必要があります。これはオーバーヘッドが多く、エラーが発生しやすくなります。したがって、追跡モデルファイルで十分です。
これはワークフローの良いトピックです。私は他のオプションを受け入れます。
manage.py makemigrations --merge
ません。私にとっては完全に自動的に機能します。
makemigrations some_app
、そのメンバーの制御下にあるモデルだけでなく、他の関連モデルにも影響が及びます。つまり、他のアプリの移行ファイル(00 * _ *)が変更されます。また、GitHubへのプッシュまたはGitHubからのプル中に、多くの競合問題が発生します。現在、システムは本番稼働の準備ができていないため.gitignore
、移行ファイルのみを使用しています。システムが本番環境に移行したときの解決方法はまだわかりません。誰かが解決策を持っていますか?