我在 Django 1.8(使用 pytest)上,我有以下配置:
- A
default
和readonly
由 a 管理的数据库MasterSlaveRouter
,根据它们是读取还是写入操作,将 DB 调用定向到一个连接或另一个连接。 - 在我的开发环境中,
settings.DATABASES
字典中的两个条目具有相同的设置(它们只是使用不同的连接,但数据库是相同的)。 - 然而,在我的测试环境中,只有一个
default
数据库。 - 每当保存模型时,我
post_save
都会触发一个信号Foo
。 - 我有一个原子操作(用 装饰
@transaction.atomic
),它修改一个Foo
实例并调用.save()
它两次。由于没有将自定义using
参数传递给装饰器,因此事务仅在default
数据库上处于活动状态。
post_save
回调创建一个指向的Bar
记录,但仅在检查是否存在带有此的记录之后(为了避免)。通过执行以下查询来完成此检查:OneToOneField
Foo
Bar
foo_id
IntegrityError
already_exists = Bar.filter(foo=instance).exists()
这在第一次post_save
调用回调时是可以的。创建了一条Bar
记录,一切正常。然而,第二次,即使Bar
在上一次保存中刚刚创建了这样一个实例Foo
,由于过滤是一个读取操作,它是使用readonly
连接执行的,因此already_exists
最终包含该值False
并触发了新记录的创建,最终会抛出一个 IntegrityError ,因为在default
连接上执行创建操作时,已经有一条带有 that 的记录foo_id
。
我尝试将DATABASES
字典从 dev_settings 复制到 test_settings,但这破坏了许多测试。然后我阅读了有关override_settings
装饰器的信息,并认为它非常适合我的情况。然而,令我惊讶的是,它没有奏效。似乎在某些时候,当应用程序启动时,DATABASES
字典(只有default
来自 test_settings 的字典)被缓存,然后即使我改变setting.DATABASES
了,新值也不再被访问。
如何正确覆盖一项特定测试的数据库配置?