0

私はdjango 1.6を使用しており、2つのモデルが次のように相互に参照しています:

class Person(models.Model):
   address = models.ForeignKey('Address', blank=False)

class Address(models.Model):
   person = models.ForeignKey(Person, blank=False)

循環外部キーを使用する理由は、データの整合性のためです。アドレスは正確に 1 人のユーザーに割り当てられる可能性があり、ユーザーは少なくとも 1 つのアドレスを持っている必要があるためです。はい、これがなくても生きていけることはわかっていますが、むしろそうはなりません。

外部キーで PostgreSQL を使用しており、DEFERRABLE INITIALLY DEFERREDトランザクションを使用してそれらのテーブルにデータを挿入したいと考えています。ただし、 を使用しようとするとtransaction.atomic():、ビュー内で期待どおりに動作しません。

これが私がやっていることです:

with transaction.atomic():
    addr = Address(street='125 fake street')
    addr.save()

    person = Person()
    person.address_id = addr.id

    addr.person_id = person.id

    addr.save()
    person.save()

しかし、私IntegrityErrorは最初に電話をかけ続けますaddr.save()

私が間違っていることは何か提案はありますか? そのためのより良い方法はありますか?

4

1 に答える 1

2

ここでの問題は、PostgreSQL がトランザクションの最後まで待たずに NOT NULL をチェックするためです。

sql-set-constraints リファレンス

「NOT NULL および CHECK 制約は、行が挿入または変更されるとすぐに (ステートメントの最後ではなく) 常にチェックされます。」

私の列はNOT NULLに設定されていました。

回避策として、私はこれをやっています

with transaction.atomic():
    addr = Address()
    addr.person_id = 0    # setting this temporarily to Zero
    addr.save()

    person = Person()
    person.address_id = addr.id
    person.save()

    addr.person_id = person.id
    addr.save()

これにより、データベースに挿入し、後で外部キーを更新できますが、外部キーが一致しない場合でも失敗します。これは、id 値の値がゼロになることはないためです。

于 2014-04-07T15:22:42.983 に答える