【发布时间】:2019-07-31 13:32:52
【问题描述】:
这里是设置
class A(Model):
pass
class B(Model):
a = ForeignKey(A, on_delete=CASCADE)
assert A.objects.all().count() == 0
try:
B.object.create(a_id=1)
except IntegrityError:
print('error')
# ... another logic to deal with situation
数据库是 PostgreSQL。目前还没有A 对象(至少有id=1)。
我尝试使用从第 3 方获取的某个假设对象 A 的 ID 创建对象 B。
期待
如果没有对象A -> IntegrityError 被抛出 -> 处理它(例如用id=1 创建对象A 并重新运行)。
现实
尽管有外键约束,对象B 仍被创建,但抛出了 IntegrityError (Key (a_id)=(1) is not present in table "app_a"),但 try/except 不会获取。一切都搞砸了。
我没有事先对get_or_create 对象A 做什么,因为每次我想创建B 时都会得到2 个查询(而且我需要多次创建它,而大部分时间都需要对象A 已经在数据库中)
编辑 1
事实证明,问题出在 pytest 上。只有内部测试我无法捕捉到IntegrityError。
with pytest.raises(IntegrityError):
b = B.objects.create(a_id=1)
尽管没有A 对象和id=1,但上面的代码没有引发IntegrityError。尽管如此,IntegrityError 的回溯会在控制台中打印出来。并创建了对象b。
【问题讨论】:
-
创建了
B对象,但没有创建B记录。当你打算插入它时,它会出错。 -
我刚刚检查过,新创建的对象
B上已经存在 id,所以它被插入了。我也可以使用B.objects.get()从数据库中获取它。 -
你没有
some_b.save(),或者使用B.objects.create(..),所以你没有在数据库端用上述逻辑做任何事情。 -
哦,有问题
-
你没有禁用外键约束,对吧?
标签: python django postgresql pytest django-orm