You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django+pytest中只读数据库镜像未同步FactoryBoy创建的数据问题

问题分析与解决方案

核心问题原因

Django的TEST.MIRROR配置是让测试环境下只读数据库复用默认数据库的连接,但你遇到的同步问题通常由以下几个原因导致:

  • 配置时机太晚:如果在测试fixture中才修改settings.DATABASES,此时Django已经初始化了数据库连接,配置变更不会生效。
  • 事务隔离机制:pytest-django默认以事务方式运行测试,FactoryBoy创建的数据处于未提交的事务中,若只读库的连接未共享该事务上下文,就无法读取到数据。
  • FactoryBoy未明确指定数据库:FactoryBoy默认使用default数据库,但如果存在自定义路由或配置,可能导致数据未写入目标库。

具体解决步骤

1. 确保配置在Django初始化前生效

将只读库的测试配置放在pytest_configure钩子中,确保在Django启动前修改settings:

# conftest.py
def pytest_configure():
    from django.conf import settings
    # 为只读库设置测试镜像
    settings.DATABASES["read_only"]["TEST"] = {"MIRROR": "default"}

2. 强制FactoryBoy使用默认数据库

在Factory类中明确指定使用default数据库,避免路由干扰:

class PaymentFactory(factory.django.DjangoModelFactory):
    class Meta:
        model = Payment
        database = "default"  # 强制指定数据库

3. 刷新只读数据库连接

如果修改配置后连接未刷新,可以在fixture中手动关闭并重建连接:

@pytest.fixture()
def populate_cache() -> Callable[[CountryFactory], Household]:
    def _populate_cache(goodcountry: CountryFactory) -> Household:
        household, individuals = create_household({"business_area": afghanistan})
        PaymentFactory.create_batch(5, household=household)
        PaymentRecordFactory.create_batch(3, household=household)

        # 关闭只读库连接,强制重新建立(应用MIRROR配置)
        from django.db import connections
        connections["read_only"].close()

        # 重新计数
        payment_count_default = Payment.objects.using("default").filter(household=household).count()
        payment_count_read_only = Payment.objects.using("read_only").filter(household=household).count()
        
        assert payment_count_read_only == payment_count_default, "默认库与只读库的Payment数量不匹配"
        return household

    return _populate_cache

4. 检查事务配置(可选)

如果上述方法无效,可以尝试禁用事务测试(不推荐,会降低测试速度),改用django_db fixture的transaction=False参数:

@pytest.mark.django_db(transaction=False)
def test_your_function(populate_cache):
    # 测试逻辑

内容的提问来源于stack exchange,提问作者iMitwe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 11:26:12