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)

我有循环外键的原因是为了数据完整性。因为一个地址可能只分配给一个用户,而一个用户必须至少有一个地址。是的,我知道没有这个我可以生活,但我宁愿不这样做。

我正在使用带有外键的 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 回答