13

假设我有 SQL Alchemy ORM 类:

class Session(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  user_agent = db.Column(db.Text, nullable=False)

class Run(db.Model):
  id = db.Column(db.Integer, primary_key=True)

  session_id = db.Column(db.Integer, db.ForeignKey('session.id'))
  session = db.relationship('Session', backref=db.backref('runs', lazy='dynamic'))

我想查询以下内容:

((session.id, session.user_agent, session.runs.count())
  for session in Session.query.order_by(Session.id.desc()))

但是,这显然是 1+n 个查询,这很糟糕。使用 1 个查询的正确方法是什么?在普通 SQL 中,我会使用以下方法来执行此操作:

SELECT session.id, session.user_agent, COUNT(row.id) FROM session
LEFT JOIN rows on session.id = rows.session_id
GROUP BY session.id ORDER BY session.id DESC
4

2 回答 2

11

构造一个子查询,对运行中的会话 id 进行分组和计数,并在最终查询中加入该子查询。

sq = session.query(Run.session_id, func.count(Run.session_id).label('count')).group_by(Run.session_id).subquery()
result = session.query(Session, sq.c.count).join(sq, sq.c.session_id == Session.id).all()
于 2013-10-21T14:42:17.800 回答
6

目标 SQL 可以简单地生成:

db.session.query(Session, func.count(Run.id)).\
    outerjoin(Run).\
    group_by(Session.id).\
    order_by(Session.id.desc())
于 2018-04-12T10:51:31.693 回答