使用SQLAlchemy执行Join查询仅返回单表列的问题求助
使用SQLAlchemy执行Join查询仅返回单表列的问题求助
嗨,我看你遇到了个SQLAlchemy的小问题——执行Join查询后只拿到了UserLibrary表的列数据,却没获取到关联的Songs表内容,对吧?我来帮你分析下原因,再给你几个解决办法~
问题原因
你用select(UserLibrary, Songs)构建了关联查询,但最后调用result.scalars().all()来获取结果。这里的关键是:scalars()方法默认只会提取查询语句中第一个实体(也就是UserLibrary)的数据,所以自然拿不到Songs的内容啦。
解决办法
方法1:直接获取完整的元组结果
当你在查询中同时选择多个实体时,execute()返回的结果集里每一行都是包含UserLibrary和Songs实例的元组,改用result.all()就能拿到完整的组合数据:
async def get_user_library(current_user = Depends(get_current_user)): async with get_session() as session: stmt = select(UserLibrary, Songs).join(Songs, UserLibrary.song_id == Songs.id).filter(UserLibrary.user_uuid == current_user) result = await session.execute(stmt) # 用all()替代scalars(),获取(UserLibrary实例, Songs实例)的元组列表 library_items = result.all() return library_items
之后你可以通过item[0]访问UserLibrary的字段,item[1]访问Songs的字段,比如item[1].title就能拿到歌曲标题。
方法2:使用ORM关联(更优雅的推荐方案)
如果给模型定义好关联关系,查询会更符合ORM的设计思路,代码也更简洁。首先给你的两个模型添加关联属性:
class Songs(Base): __tablename__ = 'songs' id = Column(Integer, primary_key=True, index=True) artist = Column(String) title = Column(String) length = Column(Integer) # 添加反向关联,关联到UserLibrary的song属性 library_entries = relationship("UserLibrary", back_populates="song") class UserLibrary(Base): __tablename__ = 'library' library_id = Column(Integer, primary_key=True, index=True) song_id = Column(Integer, ForeignKey('songs.id')) play_count = Column(Integer) added_at = Column(DateTime) user_uuid = Column(String, ForeignKey('users.uuid')) # 添加关联属性,直接关联到对应的Songs实例 song = relationship("Songs", back_populates="library_entries")
之后查询时,用joinedload来预先加载关联的歌曲数据,这样获取到的UserLibrary实例会直接带有song属性:
async def get_user_library(current_user = Depends(get_current_user)): async with get_session() as session: stmt = select(UserLibrary).options(joinedload(UserLibrary.song)).filter(UserLibrary.user_uuid == current_user) result = await session.execute(stmt) library_items = result.scalars().all() return library_items
现在你可以直接通过item.song.artist、item.song.title这样的方式访问歌曲的所有字段,不用再处理元组,代码可读性更高~
备注:内容来源于stack exchange,提问作者Kotatsu
相关产品推荐
相关产品推荐

