Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Model.objects.create() DB exception doesn't filter up

I'm trying to test constraint validation in Django with a py.test unit test by creating a child object for which the parent does not exist.

@pytest.mark.django_db
def test_child_with_missing_parent():
    with pytest.raises(django.db.utils.IntegrityError):
        Child.objects.create(parent_id=1337)

The exception is thrown, but can't be caught -- it just shows in stderr. I'm using pytest.mark.xfail for now, but it is effectively just a "skip" -- 1 xfailed, 1 xpassed is the result. How could I catch such an error in an expected scenario like this?

Here is the exception / error which appears in the console but can't be caught:

self = <django.db.backends.utils.CursorWrapper object at 0x7fe1e2dea5f8>, sql = 'SET CONSTRAINTS ALL IMMEDIATE', params = None
ignored_wrapper_args = (False, {'connection': <django.db.backends.postgresql.base.DatabaseWrapper object at 0x7fe1ec724128>, 'cursor': <django.db.backends.utils.CursorWrapper object at 0x7fe1e2dea5f8>})

    def _execute(self, sql, params, *ignored_wrapper_args):
        self.db.validate_no_broken_transaction()
        with self.db.wrap_database_errors:
            if params is None:
>               return self.cursor.execute(sql)
E               psycopg2.IntegrityError: insert or update on table "myapp_child" violates foreign key constraint "myapp_re_parent_id_537da634_fk_myapp_calc"
E               DETAIL:  Key (parent_id)=(1337) is not present in table "myapp_parent".

/usr/local/lib/python3.6/site-packages/django/db/backends/utils.py:83: IntegrityError

The above exception was the direct cause of the following exception:

self = <django.test.testcases.TestCase testMethod=__init__>
like image 768
sventechie Avatar asked Sep 03 '25 15:09

sventechie


1 Answers

Looks like you are trying to catch a different exception from what is raised. psycopg2.IntegrityError is not the same as django.db.utils.IntegrityError - and for some reason Django isn't wrapping this exception in its own wrapper.

This should work:

with pytest.raises(psycopg2.IntegrityError):
    Child.objects.create(parent_id=1337)
like image 95
solarissmoke Avatar answered Sep 05 '25 06:09

solarissmoke