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

pytest-django:fixture销毁阶段无法访问数据库的原因与解决

问题原因分析

你碰到的这个错误,核心问题是**@pytest.mark.django_db的作用范围没覆盖到fixture的销毁阶段**:

  • 你的some_fixture是scope='module'级别的,生命周期覆盖整个测试模块;
  • 测试方法上的@pytest.mark.django_db只在测试方法执行期间启用数据库访问权限;
  • 当测试方法跑完后,django_db的数据库上下文已经关闭,此时fixture中yield之后的销毁代码(app.delete())尝试访问数据库,就触发了"Database access not allowed"的限制。

简单说:测试方法的数据库权限只管测试本身,管不到module级fixture的收尾环节。

解决方案

最直接的处理方式是给fixture本身添加@pytest.mark.django_db装饰器,让fixture的整个生命周期(创建+销毁)都拥有数据库访问权限:

import pytest
from tgapps.models import TelegramApp

@pytest.fixture(scope='module')
@pytest.mark.django_db  # 把标记加到fixture上,覆盖全生命周期
def some_fixture():
    app = TelegramApp.objects.create(
        session_data=b'\xa2\x8f#',
        app_owner_phone=79856235474,
        app_id=182475,
        app_hash='aad9ab4384fea1af0342b77b606d13b0'
    )
    yield app
    print('deleting object...')
    app.delete()

其他可选方案

如果你不想给fixture加标记,也可以在销毁阶段手动用django_db的上下文管理器临时解锁数据库访问:

import pytest
from tgapps.models import TelegramApp
from pytest_django.fixtures import django_db_blocker

@pytest.fixture(scope='module')
def some_fixture(django_db_blocker):
    with django_db_blocker.unblock():
        app = TelegramApp.objects.create(
            session_data=b'\xa2\x8f#',
            app_owner_phone=79856235474,
            app_id=182475,
            app_hash='aad9ab4384fea1af0342b77b606d13b0'
        )
    yield app
    print('deleting object...')
    with django_db_blocker.unblock():
        app.delete()

不过第一种方案更简洁直观,推荐优先使用。

另外要注意:如果fixture是function级别的,测试方法上的django_db标记通常能覆盖销毁阶段,但module/class级别的fixture因为生命周期更长,必须单独给fixture配置权限。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:08:10