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

如何在SQLAlchemy中编写含LEFT JOIN子查询的语句?遇属性错误

问题:SQLAlchemy实现指定LEFT JOIN查询报错修正

目标SQL语句

需要实现的原生SQL如下:

SELECT tool.*,IF(b.id,TRUE,NULL) as liked FROM tool LEFT JOIN (
SELECT * FROM user_tool_like WHERE uid = '4d63a2bcae8e11eda9cf68fef7020cbc'
) as b  ON tool.id = b.tid
ORDER BY
tool.create_time DESC 
LIMIT 0,10

尝试代码及错误

尝试编写的SQLAlchemy代码:

subquery = db.session.query(UserToolLike).filter_by(uid=user['uid']).subquery()

query = db.session.query(Tool,subquery.id).outerjoin(subquery,Tool.id == subquery.tid)

page = db.paginate(query.order_by(desc(Tool.create_time)))
print(page)

运行后抛出错误:

File "/Users/coderd/Desktop/mypms/toolking/toolking-api/app/api/v1/tool.py", line 48, in get_tool_list
query = db.session.query(Tool,subquery.id).outerjoin(subquery,Tool.id == subquery.tid)
AttributeError: 'Subquery' object has no attribute 'id'

修正方案及正确代码

错误原因

SQLAlchemy的Subquery对象不能直接通过.访问字段,必须通过c属性(代表column)来引用子查询中的列。同时还需要实现原SQL中IF(b.id, TRUE, NULL)的逻辑。

方案一:完全对应原LEFT JOIN逻辑

from sqlalchemy import func, desc

# 子查询只需要tid字段即可,无需查询所有列
subquery = db.session.query(UserToolLike.tid).filter_by(uid=user['uid']).subquery()

# 用func.if实现原生SQL的IF判断逻辑,生成liked字段
liked_expr = func.if(subquery.c.tid.isnot(None), True, None).label('liked')

# 构建查询,通过subquery.c.tid引用子查询字段
query = db.session.query(Tool, liked_expr).outerjoin(
    subquery, Tool.id == subquery.c.tid
).order_by(desc(Tool.create_time))

# 分页,指定页码和每页数量对应原SQL的LIMIT 0,10
page = db.paginate(query, page=1, per_page=10)

方案二:用EXISTS子查询实现(性能更优)

如果只需要判断是否存在点赞记录,用EXISTS子查询无需JOIN,通常性能更好:

from sqlalchemy import exists, desc

# 构建exists子查询,判断当前tool是否被该用户点赞
liked_subquery = exists().where(
    UserToolLike.tid == Tool.id,
    UserToolLike.uid == user['uid']
)
# 将exists结果转为布尔值并命名为liked
liked_expr = liked_subquery.label('liked')

# 直接查询Tool和liked字段,无需JOIN
query = db.session.query(Tool, liked_expr).order_by(desc(Tool.create_time))

page = db.paginate(query, page=1, per_page=10)

内容的提问来源于stack exchange,提问作者coderd

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 15:10:16