如何使用sqllite在pytest中启用外键检查

时间:2017-02-15 00:42:29

标签: python django sqlite pytest

我有一个django项目,其中的测试在我调用py.test时运行,但我最近注意到它没有检查外键约束。我怎样才能检查外键约束?

显然,foreign key constraints weren't even possible until sqlite 3,但我真的不知道我正在运行什么版本,因为我没有sqlite的cli,但它只是存在django自动包含? (我使用的是django 1.9.10),但sqlite 3在2009年问世了,所以这不是问题吗?

也许it must still be enabled by the application at runtime, using the PRAGMA foreign_keys command.,但我不知道如何让我的测试做到这一点?

[UPDATE] 所以,开箱即用的sqlite看起来并不是在检查它们。

class Referenced(models.Model):
    pass

class Referencer(models.Model):
    fk = models.ForeignKey(Referenced)

>>> Referencer.objects.create(fk_id=-1)
<Referencer>
>>> Referencer.objects.all()[0].fk
DoesNotExist

3 个答案:

答案 0 :(得分:1)

我最终创建了一个解决这个问题的软件包。

pip install sqlite_checkforeignkeys

然后配置数据库:

DATABASES = {
    'default': {
        'ENGINE': 'sqlite_checkforeignkeys_engine',
        'TEST': {'NAME': ':memory:'},
    }
}

它涉及重写现有的sqlite引擎以强制执行外键

可在https://github.com/hulu/sqlite_checkforeignkeys

找到更多信息

答案 1 :(得分:0)

Python附带sqlite3。您可以通过

查看版本
import sqlite3
sqlite3.sqlite3.sqlite_version

至于设置PRAGMA语句,可能取决于所使用的驱动程序,以及您使用的是ORM。

使用peewee,您可以使用

db = SqliteDatabase('my_app.db', pragmas=(('foreign_keys', 'on')))

答案 2 :(得分:0)

即使在unittest(manage.py测试)中也不起作用,但是根据https://code.djangoproject.com/ticket/11665,它应该可以工作。

django sqlite驱动程序默认情况下使用延迟约束检查,这意味着约束是在数据库提交中检查的,这在测试中永远不会发生。上面的票应该已经修复了,但是显然没有。

我为此提交了一个新错误:https://code.djangoproject.com/ticket/29928

但是,django 2在测试之外(例如在./manage.py shell

中检查外键是否为sqlite的)