SQLAlchemy 错误:InvalidRequestError - 无法对上下文管理器内已关闭的事务进行操作

问题描述 投票:0回答:1

我在 FastAPI 项目中使用 SQLAlchemy 时遇到问题。我已经设置了一条路线,该路线应该使用上下文管理器和嵌套事务将项目添加到数据库中。如果单个项目未能添加(由于限制或任何原因),则不应将其包含在提交中。但是,应包括之前或之后添加的其余项目。

使用嵌套事务时,我希望能够跟踪失败和成功的添加。但是,我不断遇到以下错误:

sqlalchemy.exc.InvalidRequestError: Can't operate on a closed transaction inside a context manager.

我在下面提供了相关代码:

router = APIRouter()

def get_session() -> Generator[Session, None, None]:
    cached_sessionmaker = get_session_maker()
    with cached_sessionmaker.begin() as session:
        yield session

@router.post("/items")
def add_items(
    session: Session = Depends(get_database.get_session),
) -> Dict[str, Any]:

    request_inputs = [
        RequestInput(name="chair", used_for="sitting"),
        RequestInput(name="table", used_for="dining"),
        RequestInput(name="tv", used_for="watching"),
    ]

    uploaded_items = []
    failed_items = []
    for request_input in request_inputs:
        try:
            with session.begin_nested():
                item= Item(
                    **request_input.dict()
                )
                session.add(item)
                session.refresh(item)

                uploaded_items += 1

        except IntegrityError as e:
            # Handle any integrity constraint violations here
            session.rollback()
            failed_items += 1
        except Exception as e:
            # Handle other exceptions
            session.rollback()
            failed_items += 1

        session.commit()

    return {
        "uploaded": uploaded_items,
        "failed": failed_items,
    }

这显然是由于我的会话过早关闭造成的,但是我无法弄清楚在哪里提前关闭事务,同时尝试将所有未失败的项目添加到我的数据库中。有人可以帮助我理解为什么会遇到此错误以及如何修复它吗?

预先感谢您的协助。

我尝试使用 session.begin_nested() 来跟踪我的事务的状态,但是它似乎在某个地方关闭了。如果不使用 begin_nested(),我只提交失败实例之前的项目。之后的所有项目均被排除。

python sqlalchemy orm fastapi
1个回答
0
投票

该错误是由

except
块内的回滚引起的。他们回滚outer事务,使外部上下文管理器无法使用。

begin_nested()
创建的内层事务如果发生异常会自动回滚,所以不需要回滚外层事务。

© www.soinside.com 2019 - 2024. All rights reserved.