Here is the setup
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
DB is PostgreSQL. There are no A
objects yet (at least with id=1
).
I try to create object B
using the id of some hypothetical object A
fetched from the 3rd party.
If there is no object A
-> IntegrityError is thrown -> deal with it (eg create object A
with id=1
and rerun).
Object B
is created anyway despite having a foreign key constraint, IntegrityError ( Key (a_id)=(1) is not present in table "app_a"
) is thrown but is not fetched by try/except. Everything is messed up.
I don't what to get_or_create
object A
beforehand because I will end up with 2 queries every time I want to create B
(and I need to create it many times while most of the time needed object A
is already in DB)
As it turns out, the problem is with pytest. Only inside test I can't catch IntegrityError
.
with pytest.raises(IntegrityError):
b = B.objects.create(a_id=1)
Code above didn't raise IntegrityError
despite the absence of A
object with id=1
. Nonetheless IntegrityError
's traceback is printed out in the console. And object b
is created.
The problem was with trying to catch IntegrityError
inside an atomic transaction.
Guys from pytest
helped to fix it @pytest.mark.django_db(transaction=True)
instead of just @pytest.mark.django_db
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.