Django移行ファイルを.gitignoreファイルに追加する必要がありますか?


130

ファイルにDjango移行ファイルを追加する必要があり.gitignoreますか?

最近、移行の競合が原因で多くのgitの問題が発生しており、移行ファイルを無視としてマークする必要があるかどうか疑問に思っていました。

もしそうなら、自分のアプリにあるすべての移行を追加し、それらを.gitignoreファイルに追加するにはどうすればよいですか?

回答:


138

Django移行ドキュメントからの引用:

各アプリの移行ファイルは、そのアプリ内の「migrations」ディレクトリにあり、そのコードベースにコミットされ、その一部として配布されるように設計されています。開発マシンで一度作成してから、同僚のマシン、ステージングマシン、そして最終的には本番マシンで同じ移行を実行する必要があります。

このプロセスに従えば、移行ファイルでマージの競合が発生することはありません。

バージョン管理ブランチをマージする場合、同じ親の移行に基づいて複数の移行がある状況が発生する可能性があります。たとえば、異なる開発者が移行を同時に導入した場合などです。この状況を解決する1つの方法は、_merge_migration_を導入することです。多くの場合、これはコマンドで自動的に行うことができます

./manage.py makemigrations --merge

現在のすべてのヘッドマイグレーションに依存する新しいマイグレーションが導入されます。もちろん、これはヘッドの移行間に競合がない場合にのみ機能します。その場合、問題を手動で解決する必要があります。


ここで、バージョン管理への移行をコミットすべきではないとの提案があったため、実際にそうする必要がある理由を詳しく説明します。

まず、本番システムに適用された移行の記録が必要です。変更を本番環境にデプロイし、データベースを移行する場合は、現在の状態の説明が必要です。各本番データベースに適用される移行の個別のバックアップを作成できますが、これは不必要に面倒です。

次に、移行には、カスタムの手書きコードが含まれていることがよくあります。でそれらを自動的に生成できるとは限りません./manage.py makemigrations

3番目に、移行はコードレビューに含まれるべきです。それらは本番システムへの重要な変更であり、それらでうまくいかないことがたくさんあります。

つまり、本番データに関心がある場合は、バージョン管理への移行を確認してください。


24
私たち、開発者チームもまったく同じ問題を抱えています。1人のメンバーがを実行するとmakemigrations some_app、そのメンバーの制御下にあるモデルだけでなく、他の関連モデルにも影響が及びます。つまり、他のアプリの移行ファイル(00 * _ *)が変更されます。また、GitHubへのプッシュまたはGitHubからのプル中に、多くの競合問題が発生します。現在、システムは本番稼働の準備ができていないため.gitignore、移行ファイルのみを使用しています。システムが本番環境に移行したときの解決方法はまだわかりません。誰かが解決策を持っていますか?
Randy Tang

2
したがって、私がよく理解している場合は、プロジェクトから移行をプルする必要があります。あなたが何かを変えるとき、あなたは地元のmakemigrationsをしなければなりません。もう一度プッシュすると、ビルドサーバーが移行を実行しますか?(もちろん重要なことですが、誰もが良いバージョンを持っています)
lvthillo

djangoマイグレーションは決して使用しません。全員が中央のテストデータベースに接続します。変更が必要な場合は、必要に応じてdbレベルで手動で行います。この方法は、データベーススキーマの更新をあまり必要としないシステムが十分に成熟している場合に適しています。
gurel_kaynak

@ yltang52私たちは現在、それを理解しようとしていますが、洞察を共有できますか?本番環境に移行した後は、それらの移行を維持して、パッチを簡単にし、バージョン管理を全体的に容易にするしか方法がないと思います。また、初期状態データ(dbに保存されている設定など)をどのように処理するかについても考えます。それらをどのように維持しますか?
Daniel Dubovski 2016年

3
移行ファイルをリポジトリに入れるべきではないと思います。他の人の開発環境や他の製品やステージ環境での移行状態を台無しにします。(例については、Sugar Tangのコメントを参照してください)。追跡モデルファイルで十分です。
Diansheng 2018

19

以下のプロセスに従ってください。

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

3
私の意見では、移行ファイルは、アプリがデプロイされた後のリポジトリの一部にすぎません。これは初期移行としてカウントされます。アプリがまだ開発中である場合は、無視してかまいません。しかし、それがライブになると。それでおしまい!これは、移行をリポジトリに配置する必要があるという兆候です。その後、他のすべてのメンバーはこの移行に従い、必要に応じてメンバーを配置する必要があります
swdev

1
コミットされた移行のみを実行しmigrate、絶対にしないでくださいmakemigrations。そのことを考えたことはありません。
分極

9

2018年のドキュメント、Django 2.0からの引用。(2つの別々のコマンド= makemigrationsおよびmigrate

移行を作成して適用するための個別のコマンドがあるのは、バージョン管理システムへの移行をコミットして、アプリに同梱するためです。開発を容易にするだけでなく、他の開発者や本番環境でも使用できます。

https://docs.djangoproject.com/en/2.0/intro/tutorial02/


7

TL; DR:移行のコミット、移行の競合の解決、gitワークフローの調整。

競合を無視する代わりに、gitワークフローを調整する必要があるように感じます。

理想的には、すべての新機能は別のブランチで開発され、プルリクエストでマージされます。

競合がある場合、PRをマージすることはできません。そのため、移行を含め、機能をマージする必要がある人は競合を解決する必要があります。これには、異なるチーム間の調整が必要になる場合があります。

ただし、移行ファイルをコミットすることは重要です。競合が発生した場合、Djangoはそれらの競合を解決するのに役立つかもしれません ;)


それが正解です。動作するバージョン管理システムのワークフローは、djangoのドキュメントでは暗黙のように見えますが、それは基本的なものです。
エリック

3

どうにかしてマイグレーションを編集しない限り、なぜ競合が発生するの想像できませんか?これは通常はうまく終了しません。誰かがいくつかの中間コミットを見逃した場合、正しいバージョンからアップグレードされず、データベースのコピーが破損します。

私が従うプロセスは非常に単純です。アプリのモデルを変更するたびに、移行もコミットしますが、移行は変更されません。モデルに別のものが必要な場合は、モデルを変更してコミットします。変更に伴う新しい移行。

グリーンフィールドプロジェクトでは、移行を削除して、リリース時に0001_移行でゼロからやり直すことができますが、本番用のコードがある場合はできません(移行を1つにまとめることはできます)。


リリース用の0001でゼロからやり直すことの重要なポイント。
andho

3

通常使用される解決策は、マスターにマージする前に、開発者がリモートの変更をプルする必要があることです。移行バージョンに矛盾がある場合、彼はローカルの移行(リモートの移行は他の開発者によって実行されており、場合によっては本稼働中)の名前をN + 1に変更する必要があります。

開発中は、マイグレーションをコミットしないだけでも問題ない場合があります(ただし、無視は追加しないでaddください)。ただし、本番環境に移行したら、スキーマをモデルの変更と同期させるために必要になります。

次に、ファイルを編集dependenciesし、を最新のリモートバージョンに変更する必要があります。

これは、Djangoの移行や他の同様のアプリ(sqlalchemy + alembic、RoRなど)で機能します。


1

gitに多数の移行ファイルを置くのは面倒です。無視してはならないファイルが移行フォルダに1つだけあります。そのファイルはinit .pyファイルです。無視すると、Pythonはディレクトリ内のサブモジュールを検索しなくなるため、モジュールをインポートしようとしても失敗します。それで問題は、すべての移行ファイルを無視する方法であるべきですが、init .py?解決策は: '0 * .py'を.gitignoreファイルに追加すると、完全に機能します。

これが誰かを助けることを願っています。


1

開発、ステージング、本番環境用に個別のDBがある場合は、移行を無視します。開発者向け。目的ローカルのsqlite DBを使用して、ローカルで移行を試すことができます。さらに4つのブランチを作成することをお勧めします。

  1. マスター-移行せずに新鮮なコードをクリーンアップします。誰もこのブランチに接続されていません。コードレビューのみに使用

  2. 開発-毎日の開発。プッシュ/プルが受け入れられました。各開発者はsqlite DBに取り組んでいます

  3. Cloud_DEV_env-リモートのクラウド/サーバーDEV環境。プルのみ。マシン上でローカルに移行を維持します。これは、Devデータベースのコードのデプロイとリモート移行に使用されます

  4. Cloud_STAG_env-リモートクラウド/サーバーSTAG環境。プルのみ。マシンでローカルに移行を維持します。これは、Stagデータベースのコードのデプロイメントとリモート移行に使用されます

  5. Cloud_PROD_env-リモートのクラウド/サーバーDEV環境。プルのみ。マシン上でローカルに移行を維持します。これは、Prodデータベースのコードのデプロイメントとリモート移行に使用されます

注:2、3、4-移行はリポジトリに保持できますが、プルリクエストのマージには厳密なルールが必要であるため、展開を担当する人物を見つけることにしました。 -er。モデルに変更があるたびに、リモートDBの移行を維持します。


-3

短い答え 私は、レポジトリのマイグレーションを除外することを提案します。コードをマージした後、実行するだけで./manage.py makemigrations準備完了です。

長い答え 私は、マイグレーションファイルをリポジトリに置くべきではないと思います。他の人の開発環境や他の製品やステージ環境での移行状態を台無しにします。(例については、Sugar Tangのコメントを参照してください)。

私の見解では、Djangoの移行の目的は、以前のモデルの状態と新しいモデルの状態の間のギャップを見つけ、そのギャップをシリアル化することです。コードのマージ後にモデルが変更された場合は、簡単makemigrationsにギャップを見つけることができます。他の移行を自動的かつバグなく達成できるのに、手動で慎重に他の移行をマージしたいのはなぜですか?Djangoのドキュメントによれば、

それら*(マイグレーション)*は、ほとんどが自動になるように設計されています

; そのまま保管してください。移行を手動でマージするには、他の人が何を変更したか、および変更の依存関係を完全に理解する必要があります。これはオーバーヘッドが多く、エラーが発生しやすくなります。したがって、追跡モデルファイルで十分です。

これはワークフローの良いトピックです。私は他のオプションを受け入れます。


4
これはおもちゃのプロジェクトでのみ機能し、多くの欠点があります。手書きの移行、複数のエフェメラルアプリサーバーを使用するサービス(つまり深刻なアプリケーション)、および独自の移行を持つ多数のDjangoアプリで構成されるアプリの場合は、すぐに動作を停止します。そして、「手動での移行のマージ」であなたが何を参照しているか理解できmanage.py makemigrations --mergeません。私にとっては完全に自動的に機能します。
Sven Marnach

@Sven Marnach、私は確かに小さくても深刻なアプリケーションに取り組んでいました。そしてそれは私のために働きます。
ディアンシェン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.