2013-08-29 9 views
7

hereと同じように、オブジェクトはOneToOneと他のモデルとの関係で自動的に作成されます。ですからModel2にO2Oを含むModel1があり、pk = 1のModel2のオブジェクトを作成すると、Model2_id = 1のModel1のオブジェクトが自動的に作成されます。次に、DBからjsonへのIllのデータのダンプを実行すると、これらのオブジェクトに対して2つのレコードが作成されます。そして、私はこのデータをloaddataでDBにロードしようとすると、Model2のオブジェクトが2回作成され、ユニークなインデックス違反となり、IntegrityErrorが発生するため、失敗します。
誰もこれにはまったく問題ない解決策を見つけましたか?DjangoフィクスチャとOneToOneField

p.s.

http://south.readthedocs.org/en/latest/about.html

は、Djangoの1.6で来て、新しい migrations moduleは古いデータベースを置き換えます:
私は、Djangoは1.3.7

+0

解決方法を見つけましたか? –

+0

これを行う必要がある場合は、djangoを更新することをお勧めします。 – Alp

+4

ダンプデータに複数のオブジェクトが存在すると思われたり、複数回作成されたりしません。ダンプデータがあなたに与えてくれることを教えてくれますか?また、loaddataのエラー? – Rohan

答えて

0

あなたは簡単かつ強力な両方のデータ移行を行い、南を、使用して終わる可能性があり使用しますコマンドを実行し、Southを廃止します。

+0

1.7のマイグレーションが来ています...しかし、私は彼らがこのケースで助けているとは思っていません(どちらも南になりません) – OBu

+0

マイグレーションには1.7のマイグレーションがあるとの情報源を表示できますか? – Alp

+1

私たちはhttps://code.djangoproject.com/ticket/21142で議論していました。南の作者からも同じことを述べているキックスタートプロジェクトがhttp://www.kickstarter.com/projects/andrewgodwin/schemaにあります-migrations-for-django。私は1.7アルファ版でそれをテストしましたが、最初のリンクで言及されたバグは完全には解決されていませんでしたが、私にとってはうまくいかなかったのです。 – OBu

4

JSONではなくxmlで同様のことをしましたが、私のdjangoは1.7ですので、うまく動作しません。

  1. natural keysは、シリアル化されたオブジェクトを参照しているときに使用できます。これにより、インデックスがすでに他のオブジェクトによって使用されている場合、項目が混在するのを防ぐことができます。
  2. dependenciesを使用して、シリアル化の順序を定義することができます(したがって、逆シリアル化)。

this oneのような類似の投稿が役に立つかもしれません。

+0

私はこれを書いている時点でDjangoはまだ1.6をリリースしていないので、Djangoのバージョン番号が誤って入力されている可能性があります。 –

+0

いいえ、本当に最新のアルファ版を使用しています1.7 – OBu

+1

BTW: – OBu

0

のために1.7で廃止さに見えますが実際には、dumpdataloaddataなどのコマンドを使用して、データベース内の選択オブジェクトをバックアップおよび復元する場合、O2Oの関係は扱いにくくなる可能性があります。

私たちのソフトウェアでも同様の問題があり、save()メソッドをdjango.core.serializers.base.DeserializedObjectで上書きして、実際に「double」オブジェクトが保存される直前の時点までに処理することが可能であることがわかりました。この時点で、Djangoによって作成されたデフォルトのO2O関係を破棄し、フレームワークに新しいものを保存させるか、XMLまたはJSONファイルの保存された値で更新することができます。

loaddataコマンドが実行される前に、Djangoが上書きする方法を上書きする必要があります。 1つの可能性は独自のコマンドを作成して、loaddataを呼び出すことです。コマンドモジュールでは、オーバーライドをインストールします。このソリューションに関する以下の詳細が暗示されています。

  • Django 1.8でテスト済みです。X
  • 当社のO2Oフィールドがこの例では単純化のためにはDjango Userモデル
  • に装着され、私は付属のO2OフィールドAttachedと呼ぶことにします。

# Overrides deserialization to affect OneToOneFields for Users correctly 
import django.core.serializers.base 
from django.contrib.auth.models import User 
from your.attached.models import Attached #model with O2O field to User 

_original_save = django.core.serializers.base.DeserializedObject.save 

def save(self, *args, **kwargs): 

    if isinstance(self.object, Attached): 
    # if the user in question has an attached object, delete it 
    user = User.objects.get(pk=self.object.user_id) 
    if hasattr(user, 'attached'): user.attached.delete() 

    # use the built-in function for all other cases 
    _original_save(self, *args, **kwargs) 

django.core.serializers.base.DeserializedObject.save = save 

あなたは、if hasattr(...)句で、あなたの場合はそれを更新し、代わりに既存のオブジェクトを削除する、のために上記のコードを変更、削除を避けるため、からの値を持つ既存のオブジェクトを更新することができます。シリアル化されたオブジェクトを呼び出し、_original_save()への呼び出しをスキップします。既存のオブジェクトでどのフィールドを更新するかを定義する必要があるかもしれないので、コードをモデル化するためにもう少し複雑になります。上に示した解は、モデルの内容を前提にしていません。

関連する問題