Python 如何在sqlalchemy查询中返回相关实体的计数

Python 如何在sqlalchemy查询中返回相关实体的计数,python,sql,sqlalchemy,Python,Sql,Sqlalchemy,我是sqlalchemy的新手,虽然文档似乎相当全面,但我找不到一种方法来完成我想要的事情 假设我有两张桌子:论坛和帖子。每个论坛都有一个父论坛和任意数量的帖子。我想要的是: 顶级论坛列表 通过顶级论坛访问的热切加载的子论坛 每个儿童论坛的帖子数量 所以我从以下几点开始: query(Forum).filter(Forum.parent==None).all() 这给了我所有的顶级论坛。当然,访问子论坛会产生n个select查询 query(Forum).options(eagerlo

我是sqlalchemy的新手,虽然文档似乎相当全面,但我找不到一种方法来完成我想要的事情

假设我有两张桌子:论坛和帖子。每个论坛都有一个父论坛和任意数量的帖子。我想要的是:

  • 顶级论坛列表
  • 通过顶级论坛访问的热切加载的子论坛
  • 每个儿童论坛的帖子数量
所以我从以下几点开始:

 query(Forum).filter(Forum.parent==None).all()
这给了我所有的顶级论坛。当然,访问子论坛会产生n个select查询

 query(Forum).options(eagerload('children')).filter(Forum.parent==None).all()
这解决了n选择问题

现在我最好的猜测是这样的:

 query(Forum, func.count(Forum.children.posts)).options(eagerload('children')).filter(Forum.parent==None).group_by(Forum.children.id).all()
query(Forum).filter_by(parent=None).options(
    eagerload('children'),
    undefer('children.post_count'))
但我得到的只是:

AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object has an attribute 'posts'
我试过一些变化,但没有进一步的变化。为了清楚起见,我正在寻找与此SQL等效的:

select Forum.*, Child.*, count(Post.id)
from Forum
left join Forum Child on Child.parent = Forum.id
left join Message on Message.forum = Child.id
where Forum.parent is null
group by Child.id

因为您希望可以在子论坛对象上访问post count,所以在设置映射程序时需要将其声明为column属性。列属性声明应该如下所示(假设使用声明性):

然后,您可以这样表述您的查询:

 query(Forum, func.count(Forum.children.posts)).options(eagerload('children')).filter(Forum.parent==None).group_by(Forum.children.id).all()
query(Forum).filter_by(parent=None).options(
    eagerload('children'),
    undefer('children.post_count'))
另一个选项是分别选择子项和计数。在这种情况下,您需要自己进行结果分组:

ChildForum = aliased(Forum)
q = (query(Forum, ChildForum, func.count(Message.id))
        .filter(Forum.parent == None)
        .outerjoin((ChildForum, Forum.children))
        .outerjoin(ChildForum.posts)
        .group_by(Forum, ChildForum)
    )

from itertools import groupby
from operator import attrgetter

for forum, childforums in groupby(q, key=attrgetter('Node')):
    for _, child, post_count in childforums:
        if child is None:
            # No children
            break
        # do something with child

有更好的方法吗?请看我的问题