他の Django 開発者が移行を使用して複数のコード ブランチ (たとえば Git) をどのように管理しているのか興味があります。
私の問題は次のとおりです: - Git に複数の機能ブランチがあり、その一部には Django 移行が含まれています (一部はフィールドを変更したり、完全に削除したりします) - ブランチを切り替えても ( を使用git checkout some_other_branch
)、データベースに新しいコードが常に反映されるわけではないため、DB テーブル列が存在しなくなるなどの「ランダム」エラーが発生します。
今のところ、データベースを削除して再作成するだけですが、作業を再開するには大量のダミー データを再作成する必要があります。フィクスチャを使用することもできますが、どのデータがどこに保存されるかを追跡する必要があり、少し面倒です。
このユースケースに対処する良い/クリーンな方法はありますか? Git フック スクリプトで必要な移行を実行できると思いますpost-checkout
が、移行のロールバックがそもそも可能かどうかさえわかりません。
ベストアンサー1
移行のロールバックは可能であり、通常は Django によって自動的に処理されます。
次のモデルを考えてみましょう:
class MyModel(models.Model):
pass
を実行するとpython manage.py makemigrations myapp
、初期移行スクリプトが生成されます。その後、 を実行してpython manage.py migrate myapp 0001
この初期移行を適用できます。
その後、モデルにフィールドを追加する場合:
class MyModel(models.Model):
my_field = models.CharField()
その後、新しいマイグレーションを再生成して適用すると、初期状態に戻ることができます。実行するpython manage.py migrate myapp 0001
とORMは前に戻ります。削除する新しい分野。
データ移行を扱う場合は、前方および後方のコードを記述する必要があるため、さらに複雑になります。 を介して作成された空の移行を考えるとpython manage.py makemigrations myapp --empty
、次のようになります。
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
def forward(apps, schema_editor):
# load some data
MyModel = apps.get_model('myapp', 'MyModel')
while condition:
instance = MyModel()
instance.save()
def backward(apps, schema_editor):
# delete previously loaded data
MyModel = apps.get_model('myapp', 'MyModel')
while condition:
instance = MyModel.objects.get(myargs)
instance.delete()
class Migration(migrations.Migration):
dependencies = [
('myapp', '0003_auto_20150918_1153'),
]
operations = [
migrations.RunPython(forward, backward),
]
純粋なデータ読み込みの移行では、通常、後方移行は必要ありません。ただし、スキーマを変更して既存の行を更新する場合 (列内のすべての値をスラッグに変換するなど)、通常は後方移行の手順を記述する必要があります。
私たちのチームでは、衝突を避けるために、同じモデルを同時に操作しないようにしています。それが不可能で、同じ番号 (例: 0002) の移行が 2 つ作成された場合でも、そのうちの 1 つの名前を変更して、適用される順序を変更できます (dependencies
移行クラスの属性を新しい順序に更新することも忘れないでください)。
異なる機能で同時に同じモデル フィールドを操作することになった場合、依然として問題が発生しますが、これらの機能は関連しており、単一のブランチで一緒に処理する必要があることを意味する可能性があります。
mybranch
git-hooks の部分については、ブランチ上にいて別の機能ブランチをチェックアウトしたい場合、次のように記述できる可能性がありますmyfeature
。
- 切り替える直前に、現在適用されている移行のリストを一時ファイルにダンプします。
mybranch_database_state.txt
- 次に、
myfeature
ブランチ移行を適用します(必要な場合)。 - 次に、再度確認するときに
mybranch
、ダンプ ファイルを参照して以前のデータベースの状態を再適用します。
しかし、私にとってはちょっとハックっぽい感じがしますし、リベース、マージ、チェリーピッキングなど、すべてのシナリオを適切に処理するのはおそらく本当に難しいでしょう。
移行の競合が発生したときにそれを処理する方が簡単なように思えます。