Flask自引用表查询父项所有子项报sqlalchemy.exc.ArgumentError错误如何解决
问题原因
你原来的查询逻辑和join的用法存在错误,且你已经在模型中定义了自引用的child_posts关系,不需要手动编写join查询:
- 你编写的
join(Post.id==Post.parent_post)属于非法语法,自连接操作需要先给关联表设置别名 - 你的查询逻辑先过滤了主帖ID,再执行join操作只会把结果限制为同时满足
id=传入post_id和id=parent_post的记录,无法拿到子帖数据
解决方案
方案1:直接使用已定义的ORM关系(推荐)
你已经配置好了child_posts关联关系,直接查询到目标主帖后,访问它的child_posts属性就能拿到所有子帖,代码修改如下:
@posts.route("/post_thread/<int:post_id>") def post_thread(post_id): # 查询目标父帖,不存在则返回404 parent_post = Post.query.get_or_404(post_id) # 如果你需要同时返回父帖+所有子帖,就按下方写法;只需要子帖直接用parent_post.child_posts即可 posts = [parent_post] + parent_post.child_posts return render_template('post_thread.html', posts=posts, topic="Thread")
如果需要避免N+1查询问题,可以提前关联加载子帖:
from sqlalchemy.orm import joinedload @posts.route("/post_thread/<int:post_id>") def post_thread(post_id): parent_post = Post.query.options(joinedload(Post.child_posts)).get_or_404(post_id) posts = [parent_post] + parent_post.child_posts return render_template('post_thread.html', posts=posts, topic="Thread")
方案2:手动编写过滤逻辑(不使用ORM关系)
如果你不想依赖ORM的关系属性,直接过滤parent_post等于传入的post_id即可,不需要使用join:
@posts.route("/post_thread/<int:post_id>") def post_thread(post_id): parent_post = Post.query.get_or_404(post_id) # 直接过滤所有parent_post等于目标ID的帖子,就是目标主帖的所有子帖 child_posts = Post.query.filter(Post.parent_post == post_id).all() posts = [parent_post] + child_posts return render_template('post_thread.html', posts=posts, topic="Thread")
内容的提问来源于stack exchange,提问作者jeremy catchpole
相关产品推荐
相关产品推荐

