他のDjango開発者が移行で複数のコードブランチ(たとえばgit)を管理する方法に興味があります。
私の問題は次のとおりです:-gitに複数の機能ブランチがあり、その一部はDjango移行(一部はフィールドを変更するか、完全に削除する)で)-ブランチを切り替えると(git checkout some_other_branch
)データベースが常に新しいコードを反映するわけではないため、「ランダム」エラーが発生し、データベーステーブルの列がもう存在しない、など...
現時点では、dbを削除して再作成するだけですが、作業を再開するには一連のダミーデータを再作成する必要があります。フィクスチャを使用できますが、どのデータがどこに行くのかを追跡する必要があります。これは少し面倒です。
このユースケースに対処するための良い/クリーンな方法はありますか? post-checkout
gitフックスクリプトが必要な移行を実行できると思いますが、移行のロールバックが可能かどうかさえわかりません。
マイグレーションのロールバックは可能で、通常は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
属性を更新することも忘れないでください)新しい注文への移行クラス)。
異なる機能で同時に同じモデルフィールドで作業することになった場合でも問題が発生しますが、これらの機能は関連しており、1つのブランチで一緒に処理する必要があることを意味します。
Git-hooksの部分については、おそらく何かを書くことが可能です。あなたがブランチmybranch
にいて、別の機能ブランチmyfeature
をチェックアウトしたいとします:
mybranch_database_state.txt
myfeature
ブランチの移行があれば、それを適用しますmybranch
をチェックバックするときに、ダンプファイルを調べて、以前のデータベースの状態を再適用します。しかし、私には少しハックに思え、リベース、マージ、チェリーピッキングなどのすべてのシナリオを適切に処理することはおそらく本当に難しいでしょう。
移行の競合が発生したときにそれを処理することは、私には簡単に思えます。
これには良い解決策はありませんが、痛みを感じます。
チェックアウト後のフックは遅すぎます。ブランチAでブランチBをチェックアウトし、BのマイグレーションがAより少ない場合、ロールバック情報はAのみにあり、実行する必要がありますbeforeチェックアウト。
バグの原因を特定しようとする複数のコミット間をジャンプするときに、この問題に遭遇しました。私たちのデータベース(開発段階でも)は巨大なので、削除して再作成することは現実的ではありません。
私はgit-checkoutのラッパーを想像しています:
プログラミングの簡単な問題!