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

SQLAlchemy 2.0下基于PostgreSQL的pytest模块级事务隔离方案失效问题咨询

SQLAlchemy 2.0下基于PostgreSQL的pytest模块级事务隔离方案失效问题咨询

我最近在把一个老代码库从SQLAlchemy 1.3逐步迁移到2.0版本,已经顺利完成了1.3到1.4的过渡,但升级到2.0之后,测试套件里一堆模块出现了「找不到共享测试数据」的问题——奇怪的是没有SQLAlchemy底层报错,和当初从1.3升1.4时的情况完全不一样。

先给大家说下我们用的测试隔离方案:为了避免重复创建测试数据,我们用了两层嵌套事务+monkeypatch替换commit为flush的模式,在1.4下完全正常,但2.0就失效了。具体的fixture代码如下:

from sqlalchemy import Engine
from sqlalchemy.orm import Session

@pytest.fixture(scope="package")
def package_session(test_engine: Engine, monkeypatch_package) -> Session:
    # 创建包含模块级共享数据的嵌套事务
    connection = test_engine.connect()
    transaction = connection.begin()
    session = Session(bind=connection)

    # 把commit替换成flush,这样提交操作只会刷新会话,但不会结束当前事务
    monkeypatch_package.setattr(session, "commit", session.flush)

    # 创建该模块下所有测试共享的基础数据
    _create_data_for_test(session)

    try:
        yield session
    finally:
        transaction.rollback()
        connection.close()

@pytest.fixture(scope="function")
def session(package_session):
    """在外部会话上创建嵌套事务,避免回滚共享数据"""
    package_session.begin_nested()
    try:
        yield package_session
    finally:
        package_session.rollback()

简单说下逻辑:

  • 模块级的package_session会创建一个顶层事务,在里面生成共享测试数据,同时把会话的commit方法替换成flush,这样测试里的提交操作不会真正结束事务,共享数据一直存在。
  • 每个测试用例用的session fixture会在顶层事务里开一个嵌套事务(对应PostgreSQL的SAVEPOINT),测试结束后回滚这个嵌套事务,这样不会影响模块级的共享数据。

现在升级到2.0后,测试里经常出现找不到共享数据的情况,但没有任何SQLAlchemy的报错提示。我已经折腾了好几天了,实在没头绪——想问问大家,这个模式在SQLAlchemy 2.0里是不是不再支持了?或者我哪里的写法需要适配2.0的新特性?

目前我能想到的替代方案是把共享数据移到函数级fixture里,但这样每个测试都要重复创建数据,测试速度会慢很多,所以还是希望能把原来的模式修好。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 09:34:38