我使用的是Django 1.8(使用pytest),我有以下配置:
default
管理的readonly
和MasterSlaveRouter
数据库,它将数据库调用指向一个连接或另一个连接,具体取决于他们是否进行读取或写入操作。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
连接上执行创建操作时,已经存在记录foo_id
。
我尝试将DATABASES
字典从dev_settings复制到test_settings,但这打破了很多测试。然后我读到了关于override_settings
装饰者的信息,并认为这对我的情况来说是完美的。然而,令我惊讶的是,它并没有奏效。似乎在某些时候,当应用程序启动时,DATABASES
字典(仅来自test_settings的default
字典)被缓存,然后即使我更改setting.DATABASES
,新的价值根本不再被访问。
如何正确覆盖某个特定测试的数据库配置?
答案 0 :(得分:1)
现在,要覆盖django设置,最好:
from django.test import override_settings
@override_settings(DATABASE_CONFIG=<new_config>)
def test_foo():
pass
你应该试试pytest-django:
pytestmark = pytest.mark.django_db
@pytest.mark.django_db
def test_foo():
pass
运行测试时,可以设置create-db参数,强制py.test创建新数据库,或者如果要重用数据库,可以设置reuse-db,如:
$ py.test --create-db
$ py.test --reuse-db
结帐: Oficial docs