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

SQLAlchemy:CTE/group_by结果映射到ORM实体的问题

分组聚合后的SQLAlchemy结果无法映射到ORM实体

问题描述

在动态组装的复杂查询中,当特定标志开启时,需执行group_by()、sum()及group_concat()操作,但分组后无法将结果映射到ORM实体。查询本身可生成正确结果,仅映射环节失败,且需在展开步骤与连接步骤间插入分组逻辑。

场景背景

查询用于处理物料清单(BOM)树形结构数据,需支持4个动态步骤:

  • 展开步骤:通过递归CTE获取对象直接组成项或树的叶子节点;
  • 合并步骤:对相同组件分组(如合并重复电阻),此环节当前受阻;
  • 连接步骤:将结果与制造商、供应商等多表关联;
  • 筛选/排序步骤:对各类字段(含聚合结果)应用筛选和排序。

尝试方案

曾用.label()使查询结果与原表列名一致,再通过aliased(OrmEntity, subquery)或select_entity_from()映射,但ORM实体值错误,未正确获取聚合结果;也尝试为CTE新建ORM实体映射,但未找到正确方法。

相关代码

表结构

# 表结构
bom = Table('bom_details', Base.metadata,
            Column('id', Integer(), primary_key=True, autoincrement=True),
            Column('bd_bh_mag_id', Integer()),
            Column('bd_bh_revisione', String()),
            Column('bd_mag_id', Integer()),
            Column('bd_mag_id_revisione', String()),
            Column('bd_topografia', String()),
            Column('bd_flag_non_montare', Integer()),
            Column('bd_progressivo', Integer()),
            Column('bd_descrizione', String()),
            Column('bd_note', String()),
            Column('bd_qta', String()),
            ForeignKeyConstraint(['bd_bh_mag_id', 'bd_bh_revisione', 'bd_mag_id', 'bd_mag_id_revisione'],
                                 ['anamag.mag_id', 'anamag.mag_code_revision', 'anamag.mag_id', 'anamag.mag_code_revision'])
)

ORM映射

# ORM映射
mapper_registry.map_imperatively(
    BomItem,
    bom,
    properties={
        "descrizione" : column_property(bom.c.bd_descrizione),
        "nm": column_property(bom.c.bd_flag_non_montare),
        "index": column_property(bom.c.bd_progressivo),
        "refdes": column_property(bom.c.bd_topografia),
        "note": column_property(bom.c.bd_note),
        "qty": column_property(bom.c.bd_qta),
        "parent_anamag": relationship("AnamagItem", lazy='joined',
                               primaryjoin=(bom.c.bd_bh_mag_id == AnamagItem.iit_code) &
                               (bom.c.bd_bh_revisione == AnamagItem.revision)),
        "anamag": relationship("AnamagItem", lazy='joined',
                               primaryjoin=(bom.c.bd_mag_id == AnamagItem.iit_code) &
                               (bom.c.bd_mag_id_revisione == AnamagItem.revision)),
    },
)

合并步骤实现

# 合并步骤实现
def _query_imploded(self, q):
    q = q.subquery()

    subq = self.db.session.query(
        literal('0').label("bd_bh_mag_id"),
        literal('0').label("bd_bh_revisione"),
        q.c.bd_mag_id,
        q.c.bd_mag_id_revisione,
        func.group_concat(q.c.bd_topografia, separator=', ').label("bd_topografia"),
        func.group_concat(q.c.bd_flag_non_montare, separator=', ').label("bd_flag_non_montare"),
        func.group_concat(q.c.bd_progressivo, separator=', ').label("bd_progressivo"),
        literal('').label("bd_descrizione"),
        func.group_concat(q.c.bd_note, separator=', ').label("bd_note"),
        func.sum(q.c.bd_qta).label("bd_qta")
    ).group_by(q.c.bd_mag_id, q.c.bd_mag_id_revisione).cte("implode_cte")

    #res = self.db.session.query(aliased(self.db.BomItem, subq))
    #res = self.db.session.query(self.db.BomItem).select_entity_from(subq)

其中q为展开步骤生成的查询或递归CTE,最终结果需传入连接步骤进行关联、筛选和排序。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 15:40:16