如何查询 SQLAlchemy 到 return 相关记录的总和值?

How to query SQLAlchemy to return a summed value of related records?

我正在创建一个小程序来跟踪用户执行的任务。每个任务都有一个值。如果用户执行了任务,则会在第三个 table(称为 Stripe)中创建一个新条目,用于保存用户和执行的任务。

我的模型是这样的:

class User(db.Model):
    __tablename__ = 'user'
    # ...
    id = db.Column(db.Integer, primary_key=True)
    stripes = db.relationship(Stripe, backref=db.backref('related_user'), lazy='select')

class Task(db.Model):
    __tablename__ = 'task'
    # ...
    id = db.Column(db.Integer, primary_key=True)
    value = db.Column(db.Integer, nullable=False)
    stripes = db.relationship(Stripe, backref=db.backref('related_task'), lazy='select')


class Stripe(db.Model):
    __tablename__ = 'stripe'
    # ...
    id = db.Column(db.Integer, primary_key=True)
    task = db.Column(db.Integer, db.ForeignKey('task.id'), nullable=False)
    user = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

我无法获取用户执行的所有 value 任务的总数 (sum)。 预期输出:

User ID Total stripe value Additional user Columns
User_1 3 ...
User_2 10 ...
User_3 0 ...

我试过:

但这不会 return 任何没有条纹的用户。我希望它成为 return 0 然后。

最后一条语句 returns AttributeError: 'InstrumentedList' object has no attribute 'task'。为什么我不能通过这种方式访问​​任务?

我如何查询我的模型,以便它 return 为用户 table 添加一个额外的列 Total Stripes Value? (该用户所有已执行任务的总价值)

对于不匹配的用户,您需要使用 outer join to include rows that can't join because their is no matching record (ie. no stripes). Join from users to stripes to tasks so that you can get the task value. Use func.sum to add the values up. Use func.coalesceNULL 转换为 0,即。没有条纹的用户。您可以在您使用的任何基础数据库的文档中找到 LEFT OUTER JOINSUMCOALESCE

q = session.query(User, func.coalesce(func.sum(Task.value), 0)).outerjoin(User.stripes).outerjoin(Stripe.related_task).group_by(User.id)
for user, value_total in q.all():
    print(user, value)

为了引用用户的任务,您需要遍历条带并根据您的反向引用使用 related_task,如下所示:

tasks = [stripe.related_task for stripe in user.stripes]