【问题标题】:Django Model.objects.create() DB exception doesn't filter upDjango Model.objects.create() DB 异常没有过滤
【发布时间】:2018-06-28 22:11:29
【问题描述】:

我正在尝试使用 py.test 单元测试通过创建一个父对象不存在的子对象来测试 Django 中的约束验证。

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

异常被抛出,但无法被捕获——它只显示在stderr 中。我现在使用pytest.mark.xfail,但它实际上只是一个“跳过”——1 xfailed, 1 xpassed 是结果。我怎么能在这样的预期场景中捕捉到这样的错误?

这是出现在控制台中但无法捕获的异常/错误:

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__>

【问题讨论】:

  • 你确定抛出了异常吗?如果您手动指定外键 ID,那么 Django 将只设置该值 - 它不会检查具有该 ID 的父级是否实际存在。如果您随后尝试获取 child.parent,您只会得到一个异常 (DoesNotExist)。
  • 在 stderr 中(在控制台中)抛出异常并带有堆栈跟踪,但在 except Exception as e: 中没有显示任何内容

标签: python django exception-handling pytest psycopg2


【解决方案1】:

看起来您正试图捕获与引发的异常不同的异常。 psycopg2.IntegrityErrordjango.db.utils.IntegrityError 不同 - 出于某种原因,Django 没有将这个异常包装在自己的包装器中。

这应该可行:

with pytest.raises(psycopg2.IntegrityError):
    Child.objects.create(parent_id=1337)

【讨论】:

  • 不怕,它只是说Failed: DID NOT RAISE &lt;class 'psycopg2.IntegrityError'&gt;。我尝试从django.dbdjango.db.utils 捕获IntegrityError,因为其他SO 帖子表明ORM 经常包装低级异常。
猜你喜欢
  • 2014-12-27
  • 1970-01-01
  • 1970-01-01
  • 2012-08-24
  • 1970-01-01
  • 2014-02-17
  • 1970-01-01
  • 2019-08-01
  • 2016-04-05
相关资源
最近更新 更多