嵌套会话after_transaction_end需要 SQL Alchemy v2

SQL Alchemy v2 is after_transaction_end needed for nested session

提问人:Intrastellar Explorer 提问时间:11/16/2023 更新时间:11/18/2023 访问量:32

问:

在设置基于 SQLAlchemy 和 Pytest 的测试套件(2022 年 5 月随 SQLAlchemy v1 一起发布)中,它使用以下代码片段进行事务测试。注意:我在这篇文章中清理了一下:

# conftest.py

import pytest

# Import a session factory in our app code. Possibly created using
# `sessionmaker()`
from myapp.db import Session

@pytest.fixture(autouse=True)
def session(connection):
    transaction = connection.begin()
    session = Session(bind=connection)
    session.begin_nested()

    @event.listens_for(session, "after_transaction_end")
    def restart_savepoint(db_session, ended_transaction):
        if ended_transaction.nested and not ended_transaction._parent.nested:
            session.expire_all()
            session.begin_nested()

    yield session

    Session.remove()
    transaction.rollback()

我现在在 2023 年 11 月使用 SQLAlchemy v2,并对内部函数有三个问题:restart_savepoint

  • 你能解释一下其中的逻辑吗?ended_transaction.nested and not ended_transaction._parent.nested
  • SQL Alchemy v2 是否仍需要此行为?restart_savepoint
  • SQL Alchemy v2 仍然需要吗?Session(bind=connection)

我认为以下内容同样可行:

@pytest.fixture(autouse=True)
def session(connection):
    with Session() as session, session.begin(nested=True):
        yield session
蟒蛇 SQL炼金术

评论


答:

2赞 VonC 11/18/2023 #1

ended_transaction.nested and not ended_transaction._parent.nested:

该逻辑用于检测顶级嵌套事务的结束。以下是细分:

  • ended_transaction.nested:检查刚刚结束的事务是否嵌套。
  • not ended_transaction._parent.nested:确保其父事务未嵌套。

综合起来,这意味着区块内的代码仅在顶级嵌套事务结束时运行,而不是在非嵌套事务或子嵌套事务结束时运行。if


在 SQLAlchemy v2 中是必需的吗?restart_savepoint

我怀疑不是,考虑到它在提交 d050193 中删除,名为“完全实现未来引擎并删除遗留”


还需要吗?Session(bind=connection)

在 SQLAlchemy v2 中,如果使用上下文管理器模式 (),则通常不需要将会话显式绑定到连接。会话将自动管理连接生命周期。但是,如果您有特定要求,例如在多个会话中重用现有连接,您可能仍需要手动绑定。
您仍然可以在提交 6bf32f5 中找到它
with Session() as session


您建议的代码:

@pytest.fixture(autouse=True)
def session(connection):
    with Session() as session, session.begin(nested=True):
        yield session

这是在 SQLAlchemy v2 中处理会话的一种更简洁、更惯用的方法。它利用上下文管理器来处理会话和事务生命周期,这是 SQLAlchemy v2 中的推荐做法。有关详细信息,请参阅会话基础知识