You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQLAlchemy中如何将外键关联表的字段求和值作为主表行的属性?

SQLAlchemy子表字段求和关联到主表的实现方法

首先给出示例对应的基础ORM模型定义:

from sqlalchemy import Column, Integer, String, ForeignKey, func, select
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.hybrid import hybrid_property

Base = declarative_base()

# 主表模型
class Table1(Base):
    __tablename__ = "table1"
    id = Column(Integer, primary_key=True)
    name = Column(String)
    description = Column(String)
    # 关联子表
    table2_items = relationship("Table2", backref="table1")

# 子表模型
class Table2(Base):
    __tablename__ = "table2"
    id = Column(Integer, ForeignKey("table1.id"), primary_key=True)
    value = Column(Integer)

方法1:临时关联聚合查询

适合单次查询场景,直接在查询语句中关联子表做聚合计算:

# session为已初始化的SQLAlchemy会话实例
result = session.query(
    Table1.id,
    Table1.name,
    Table1.description.label("desc"),
    func.sum(Table2.value).label("sum(value)")
).join(
    Table2, Table1.id == Table2.id
).filter(
    Table1.id == 1
).group_by(
    Table1.id, Table1.name, Table1.description
).first()

# 输出结果:(1, 'test1', 'desc1', 11)
print(result)

如果需要保留无关联子表的主表记录,求和返回0,改用外连接加空值处理:

result = session.query(
    Table1.id,
    Table1.name,
    Table1.description.label("desc"),
    func.coalesce(func.sum(Table2.value), 0).label("sum(value)")
).outerjoin(
    Table2, Table1.id == Table2.id
).filter(
    Table1.id == 1
).group_by(
    Table1.id
).first()

方法2:混合属性复用求和逻辑

如果需要频繁使用该求和字段,可以在主表模型中定义混合属性,简化后续查询逻辑。
在Table1模型中新增以下代码:

@hybrid_property
def value_sum(self):
    # 实例层面的求和逻辑,适用于已经加载了子表数据的场景
    return sum(item.value for item in self.table2_items)

@value_sum.expression
def value_sum(cls):
    # SQL表达式层面的求和逻辑,适用于查询语句中直接调用
    return select(func.sum(Table2.value)).where(Table2.id == cls.id).scalar_subquery()

后续查询可直接调用该属性:

# 查询单条主表记录带求和值
item = session.query(Table1, Table1.value_sum).filter(Table1.id == 1).first()
# 输出:test1 11
print(item.Table1.name, item.value_sum)

# 批量查询所有主表记录带求和值
all_items = session.query(Table1.id, Table1.name, Table1.value_sum).all()

内容的提问来源于stack exchange,提问作者MISHANDLED

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 13:45:03