如您所述,上述解决方案不起作用的真正原因是
joinedload标题中的。您可以采取以下措施:
选项1:joinedload
对此查询禁用
q = (db.session.query(Post, func.count(likes.c.user_id).label("total")) .options(lazyload(Post.headings)) # disable joined-load .join(likes) .group_by(Post) .order_by('total DESC') )如果确实需要标题,则可以使用
subqueryload:
q = (db.session.query(Post, func.count(likes.c.user_id).label("total")) .options(subqueryload(Post.headings)) .join(likes) .group_by(Post) .order_by('total DESC') )选项2:使用子查询
subq = (db.session.query( Post.id.label("post_id"), func.count(likes.c.user_id).label("num_likes")) .outerjoin(likes).group_by(Post.id) ).subquery("subq")q = (db.session.query(Post, subq.c.num_likes) .join(subq, Post.id == subq.c.post_id) .group_by(Post) .order_by(subq.c.num_likes.desc()) )选项3:使用混合属性
它可能不是最有效的,但是可以保持干净。
在
Post模型中添加以下内容:
from sqlalchemy.ext.hybrid import hybrid_propertyclass Post(db.Model): # ... @hybrid_property def num_likes(self): return len(self.likes) @num_likes.expression def _num_likes_expression(cls): return (db.select([db.func.count(likes.c.user_id).label("num_likes")]) .where(likes.c.post_id == cls.id) .label("total_likes") )稍后,您可以采用一种简洁的方式来组成查询:
q = db.session.query(Post, Post.num_likes).order_by(Post.num_likes.desc())# use this if you need it data sorted, but do not care how many likes are there #q = db.session.query(Post).order_by(Post.num_likes.desc())



