0

0

Pytest 测试发现阶段触发 SQLite 数据库文件打开失败的解决方案

心靈之曲

心靈之曲

发布时间:2026-01-04 13:23:43

|

949人浏览过

|

来源于php中文网

原创

Pytest 测试发现阶段触发 SQLite 数据库文件打开失败的解决方案

pytest 在测试发现(test discovery)阶段即执行 database.py 中的顶层连接代码,导致在 conftest.py 的 patch 生效前就尝试访问未存在的数据库文件,引发 sqlite3.operationalerror。根本解法是延迟数据库连接初始化,改用按需创建的上下文管理器或函数式连接工厂。

该问题本质是模块导入时的副作用(import-time side effect):当 test_database.py 导入 from src.database import LOCAL_SESSION 时,Python 会立即执行 database.py 全局作用域中的代码——包括 sqlite3.connect(...) 调用。而此时 conftest.py 中的 @pytest.fixture(autouse=True) 尚未运行(fixture 在测试执行阶段才被注入),Config().table_db_path 仍为原始值(如 "./prod.db"),导致 SQLite 尝试打开一个不存在的生产路径,报错中断测试发现流程。

✅ 正确做法:消除模块级连接,将数据库连接封装为可延迟调用的对象。推荐使用以下任一方案:

Amazon Nova
Amazon Nova

亚马逊云科技(AWS)推出的一系列生成式AI基础模型

下载

方案一:函数式连接工厂(推荐,简洁清晰)

# database.py
import sqlite3
from urllib.request import pathname2url
from .config import Config

def get_local_session():
    """按需创建只读 SQLite 连接,支持测试环境动态配置"""
    db_path = Config().table_db_path
    dburi = f"file:{pathname2url(db_path)}?mode=r"
    return sqlite3.connect(dburi, uri=True)
# test_database.py
from src.database import get_local_session

def test_should_return_true_when_read_from_db_is_given():
    with get_local_session() as conn:  # 每次测试独立连接
        cursor = conn.cursor()
        cursor.execute("SELECT count(*) AS tot FROM table")
        assert cursor.fetchone()[0] == 1

方案二:上下文管理器类(适合复杂连接逻辑)

# database.py
import sqlite3
from urllib.request import pathname2url
from .config import Config

class LocalSession:
    def __enter__(self):
        db_path = Config().table_db_path
        dburi = f"file:{pathname2url(db_path)}?mode=r"
        self._conn = sqlite3.connect(dburi, uri=True)
        return self._conn

    def __exit__(self, exc_type, exc_val, exc_tb):
        if hasattr(self, '_conn'):
            self._conn.close()

def get_local_session():
    return LocalSession()
# test_database.py
from src.database import get_local_session

def test_should_return_true_when_read_from_db_is_given():
    with get_local_session() as conn:
        cursor = conn.cursor()
        cursor.execute("SELECT count(*) AS tot FROM table")
        assert cursor.fetchone()[0] == 1

关键注意事项:

  • 禁止在模块顶层(global scope)执行 sqlite3.connect()、open()、requests.get() 等 I/O 操作;
  • ✅ conftest.py 中的 autouse=True fixture 仅在测试执行阶段生效,无法影响导入时行为;
  • ✅ 若需复用连接(如性能敏感场景),应通过 session-scoped fixture 显式管理生命周期,而非模块变量;
  • ✅ 测试数据库路径(如 ./tests/resources/ase_service.db)需确保在测试前已存在或由 fixture 自动初始化。

通过将连接逻辑从“导入即执行”改为“调用即创建”,彻底规避了 pytest 发现阶段的提前失败,同时提升了代码的可测性与健壮性。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
session失效的原因
session失效的原因

session失效的原因有会话超时、会话数量限制、会话完整性检查、服务器重启、浏览器或设备问题等等。详细介绍:1、会话超时:服务器为Session设置了一个默认的超时时间,当用户在一段时间内没有与服务器交互时,Session将自动失效;2、会话数量限制:服务器为每个用户的Session数量设置了一个限制,当用户创建的Session数量超过这个限制时,最新的会覆盖最早的等等。

336

2023.10.17

session失效解决方法
session失效解决方法

session失效通常是由于 session 的生存时间过期或者服务器关闭导致的。其解决办法:1、延长session的生存时间;2、使用持久化存储;3、使用cookie;4、异步更新session;5、使用会话管理中间件。

776

2023.10.18

cookie与session的区别
cookie与session的区别

本专题整合了cookie与session的区别和使用方法等相关内容,阅读专题下面的文章了解更详细的内容。

97

2025.08.19

discuz database error怎么解决
discuz database error怎么解决

discuz database error的解决办法有:1、检查数据库配置;2、确保数据库服务器正在运行;3、检查数据库表状态;4、备份数据;5、清理缓存;6、重新安装Discuz;7、检查服务器资源;8、联系Discuz官方支持。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

228

2023.11.20

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

390

2023.06.29

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2112

2023.08.14

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

359

2023.08.31

MySQL恢复数据库
MySQL恢复数据库

MySQL恢复数据库的方法有使用物理备份恢复、使用逻辑备份恢复、使用二进制日志恢复和使用数据库复制进行恢复等。本专题为大家提供MySQL数据库相关的文章、下载、课程内容,供大家免费下载体验。

259

2023.09.05

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

49

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 5万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号