【问题标题】:Is it possible to use an in-memory SQLite database when testing Flask with Peewee ORM?使用 Peewee ORM 测试 Flask 时是否可以使用内存中的 SQLite 数据库?
【发布时间】:2021-11-18 11:18:54
【问题描述】:

我正在为我的 Flask Web 应用程序编写测试,并在尝试测试与数据库交互的端点时遇到了错误。

我的client 夹具试图遵循Flask's testing tutorial 的精神:

DATABASE = {
    "engine": "SqliteDatabase",
    "name": ":memory:",
}


@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)
            init_database()
        yield client

但是在尝试运行最简单的测试时,

def test_test_endpoint(client):
    client.post("/test")

我收到peewee.OperationalError: Connection already opened.

我已经知道db_wrapper 在我调用init_database 时会打开一个连接,并且connect_db 是由FlaskDB 包装器设置的Flask 的preprocess_request 调用的。

为了测试,即使它会擦除我的 SQLite 内存数据库中的所有数据,我尝试在 init_database 之后调用 db_wrapper.database.close(),但得到了同样的错误,所以即使有一个 in-内存测试数据库不太理想,看来我的问题无法通过将数据移动到磁盘来解决。

【问题讨论】:

  • 什么是db_wrapperdb_wrapper.init_app() 是做什么的?您是否安装了在每个请求上打开/关闭数据库的请求挂钩?内存数据库只在连接期间存在,因此您必须确保在测试期间不要关闭它。
  • 嗨@coleifer!感谢您的回复,我喜欢您的项目! db_wrapperFlaskDB 的一个实例。我仔细阅读了playhouse/flask_utils.py 中的代码,我知道在调用db_wrapper.init_app() 时它会在内部调用_register_handlers(app),它会安装挂钩来打开/关闭数据库连接。在使用FlaskDB 包装器时,您所描述的情况是否可能“因此您必须确保在测试期间不会关闭它”?我的意思是,内部调用create_tablesinit_database 已经打开了数据库,关闭连接意味着数据消失了。

标签: flask pytest peewee


【解决方案1】:

在通过 peewee 的 IRC 频道 (#peewee @libera.chat) 与 @coleifer 交谈后,得出的结论是有两种选择,

  1. 子类FlaskDB 并阻止它在_register_handlers(app) 注册请求处理程序
  2. 使用tempfile

原因是SQLite:memory:模式是一种特殊模式,每次断开连接都会丢失数据,而FlaskDB的一个特点是它负责创建和终止连接到每次请求之前和之后的数据库。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 1970-01-01
    • 2010-11-29
    • 1970-01-01
    • 2021-04-16
    • 1970-01-01
    • 2021-09-15
    相关资源
    最近更新 更多