2017-07-27 6 views
1

I次のシナリオがあります。ジャンゴ - 別のモデルに属性を移動および削除する方法、それ

class C(): 
    y = models.Integer... 
    z = models.Integer... 

class D(): 
    y2 = models.Integer... 
    z2 = models.Integer... 

私は属性yからデータをコピーし、Y2にそれを貼り付けるに。さて、私は仕事をするデータ移行を作成しました。私はまた、コードは次のようになりますので、クラスCから属性を削除したい

from greatapp.models import C, D 

class Migration(migrations.Migration): 

    def move_info_to_class_d(apps, schema_editor): 
     objs = C.objects.all() 

     for obj in objs.iterator(): 
      d = D.objects.create(y2=obj.y) 

    operations = [ 
     migrations.RunPython(move_info_to_class_d) 
    ] 

お知らせ:一言で言えば

class C(): 
    z = models.Integer... 

class D(): 
    y2 = models.Integer... 
    z2 = models.Integer... 

すべてが右、OKに見えますか?コミットする時間。

ああ、待ってください!このコードを実行する次の人は、データ移行がもはや存在しない属性(この場合はy)にアクセスしようとしているため、エラーが発生します。

属性を別のモデルクラスにコピーしてソースクラスから削除する回避策(.sqlファイルは不要)を知っていますか?

答えて

0

だからこそ、データ移行の引数はappsです。データ移行を作成したときのモデルの定義を保持します。

ので

def move_info_to_class_d(apps, schema_editor): 
    C = apps.get_model('yourappname', 'C') 
    D = apps.get_model('yourappname', 'D') 

    objs = C.objects.all() 

    for obj in objs.iterator(): 
     d = D.objects.create(y2=obj.y) 

を行うと、それは(限り、あなたはこの1つの後C.yを削除し、移行を作成して)正常に動作します。

編集:ああ、objs.iterator()は不要です。objsは既にそれ自体で繰り返し可能です。

+0

これは、感謝しました! ps:私はiterator()を使用して内部キャッシュを無効にしました。これは、私のPCがループなしで実行されているときにメモリが不足していたからです(本当に大きなデータセットです) – almanegra

関連する問題