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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 16:06:04