Fastapi SqlAlchemy 会话返回一个空对象?但是当我打印它时它的实际数据在那里

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

我的应用程序使用

fastapi==0.109.2
SQLAlchemy==2.0.27

所以我的 sql 连接和会话工作正常,但我从 sqlalchemy 中得到了一些错误,我改变了连接方式以使用 contextmanager,如下所示:



@contextlib.contextmanager
def session_scope():
    db_engine = create_engine(url) # echo=True if needed to see background SQL        
    Session = sessionmaker(bind=db_engine)
    session = Session()
    try:
        yield session
        session.commit()
    except:
        print("Error")
        session.rollback()
        raise
    finally:
        session.close()

然后我导入它并在此处使用它,如您所见,我在那里有 2 个打印,第一个显示实际数据,第二个(这是端点返回的内容)是空对象,我似乎找不到问题...

@router.get("/me")
def getusers(dependencies=Depends(JWTBearer())):
    user = None
    with session_scope() as sess:
        x = sess.query(TokenTable).where(TokenTable.access_toke == dependencies).first()
        user = sess.query(User).where(User.id == x.user_id).first()
        print(user.__dict__)
    print(user.__dict__)
    return user

日志:

INFO:     127.0.0.1:40662 - "GET /users/me HTTP/1.1" 200 OK
{'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x7f11ef2bfc40>, 'first': 'Deez', 'last': 'Nuts', 'email': '[email protected]', 'id': 2, 'is_active': True, 'coach': None}
{'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x7f11ef2bfc40>}
INFO:     127.0.0.1:40662 - "GET /users/1/logs HTTP/1.1" 200 OK
INFO:     127.0.0.1:40656 - "GET /users/me HTTP/1.1" 200 OK

我阅读了很多 sqlachemy 文档,也在这里发现了一些问题,但没有一个涉及这个特定主题。

python mysql sqlalchemy fastapi
1个回答
0
投票

您面临的问题可能是因为一旦您使用 session_scope() as sess: 退出上下文管理器,您正在查询的会话就会关闭。这意味着,当您尝试在会话之外访问 user.dict 时,SQLAlchemy 无法延迟加载任何数据,因为会话不再活动。

要解决此问题,您可以尝试在会话中使用 joinload 立即加载数据。具体方法如下:

from sqlalchemy.orm import joinedload

@router.get("/me")
def getusers(dependencies=Depends(JWTBearer())):
    user = None
    with session_scope() as sess:
        x = sess.query(TokenTable).where(TokenTable.access_toke == dependencies).first()
        user = sess.query(User).options(joinedload('*')).where(User.id == x.user_id).first()
        user_data = user.__dict__.copy()  # create a copy of user data
        print(user_data)
    print(user_data)
    return user_data

通过使用

joinedload('*')
,SQLAlchemy 将立即加载
User
的所有属性,因此即使会话关闭后您仍然可以稍后访问它们。

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