繁体   English   中英

如何使用SqlAlchemy通过联接构造计数聚合?

[英]How can I construct a count aggregation over a join with SqlAlchemy?

我有一个用户表,一个这些用户可能属于的组表以及一个用户与组之间的联接表。

这在SQLAlchemy中表示如下:

class User(Base):
    __tablename__ = 'user'
    user_id = Column(Integer, primary_key=True)
    name = Column(String(250), nullable=False)
    email = Column(String(250), nullable=False)
    groups = relationship('Group', secondary='user_group_pair')

class Group(Base):
    __tablename__ = 'group'
    group_id = Column(Integer, primary_key=True)
    name = Column(String(250), nullable=False)
    date_created = Column(String(250), nullable=False)
    members = relationship('User', secondary='user_group_pair')

class User_Group_Pair(Base):
    __tablename__ = 'user_group_pair'
    user_group_pair_id = Column(Integer, primary_key=True)
    user_id = Column(Integer, ForeignKey('user.user_id'))
    group_id = Column(Integer, ForeignKey('group.group_id'))
    user = relationship(User, backref=backref("group_assoc"))
    group = relationship(Group, backref=backref("user_assoc"))

我正在尝试解决以下简单问题:

我想编写一个查询,该查询将返回用户列表以及每个用户所属的组的数量。

这需要来自User和User_Group_Pair的数据(因此,我的问题的标题为何指向联接),以及由user_id分组的计数汇总。

我不确定为什么这行不通:

subq = session.query(User_Group_Pair.user_id.label('user_id'), func.count(User_Group_Pair.user_group_pair_id).label('count')).\
group_by(User_Group_Pair.user_id).order_by('count ASC').subquery()

result = session.query(User).join(subq, User.user_id == subq.user_id).all()

我收到此错误:

'Alias' object has no attribute 'user_id'

但是,请注意,我已经将User_Group_Pair.user_id标记为“ user_id” ...有什么想法吗?

谢谢

http://docs.sqlalchemy.org/en/rel_1_0/orm/tutorial.html#using-subqueries

Query上的subquery()方法产生一个SQL表达式构造,该构造表示嵌入在别名中的SELECT语句。 可以通过名为c的属性访问该语句上的列。

您可以在查询中使用带有.c.column_name列名

result = session.query(User).join(subq, User.user_id == subq.c.user_id).all()

只需将subq.user_id更改为subq.c.user_idc代表columns )即可使其工作:

result = session.query(User).join(subq, User.user_id == subq.c.user_id).all()

但是,您仍然只会获得至少属于一个组的那些用户,并且查询结果中不会真正返回组的数量。 以下查询是解决此问题的一种方法:

q = (session.query(User, func.count(Group.group_id).label("num_groups"))
     .outerjoin(Group, User.groups)
     .group_by(User.user_id)
     )
for b, num_groups in q:
    print(b, num_groups)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM