Django如何插入相互引用的表格

0 投票
1 回答
3881 浏览
提问于 2025-04-18 01:39

我正在使用django 1.6,并且有两个模型互相引用,像这样:

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()

但是,我每次调用addr.save()时都会遇到一个IntegrityError错误。

有没有人能告诉我我哪里做错了?有没有更好的方法来实现这个?

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 值永远不会是零。

撰写回答