Flask搭配Peewee ORM测试时能否使用内存SQLite数据库?
错误根因
报错是两个数据库连接打开逻辑冲突导致:
- fixture中执行
init_database()时,db_wrapper已经打开了一次数据库连接 - FlaskDB绑定的
preprocess_request钩子在请求进入时,会再次调用connect_db(),peewee默认不允许同一连接实例重复打开,直接抛出peewee.OperationalError: Connection already opened.
你之前尝试手动关闭连接无效的原因:一方面
:memory:类型的SQLite数据库会在连接关闭时直接销毁所有已初始化的表结构,就算后续连接成功也会出现表不存在的错误;另一方面手动关闭没有同步FlaskDB的内部连接状态标记,钩子触发时还是会认为需要打开新连接,因此报错无法解决。
修复方案
方案1:用数据库上下文管理初始化阶段的连接
在初始化数据库时使用peewee提供的上下文管理器,执行完初始化操作后自动清理连接状态,不会残留连接标记:
@pytest.fixture def client(): app = create_app({"TESTING": True, "DATABASE": DATABASE}) with app.test_client() as client: with app.app_context(): db_wrapper.init_app(app) # 上下文会自动管理连接生命周期,结束后清理状态 with db_wrapper.database: init_database() yield client
方案2:测试环境跳过自动连接钩子
直接移除测试环境下FlaskDB注册的preprocess_request自动连接钩子,避免重复调用连接逻辑:
@pytest.fixture def client(): app = create_app({"TESTING": True, "DATABASE": DATABASE}) # 移除自动连接的前置请求钩子 for hook in app.before_request_funcs.get(None, []): if hook.__name__ == "connect_db": app.before_request_funcs[None].remove(hook) break with app.test_client() as client: with app.app_context(): db_wrapper.init_app(app) init_database() yield client
方案3:允许连接复用
修改连接逻辑,调用connect时添加reuse_if_open=True参数,重复调用连接时如果已经打开就直接复用现有连接,不会报错:
# 对应你的connect_db钩子逻辑修改 def connect_db(): db_wrapper.database.connect(reuse_if_open=True)
内容的提问来源于stack exchange,提问作者Pathong
相关产品推荐
相关产品推荐

