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

如何在SQLAlchemy中用array_agg()关联查询获取Product表数据数组?

问题

我希望使用array_agg函数获取Product表的数据数组,该功能在PostgreSQL中可正常运行,但在SQLAlchemy中似乎仅支持整数、字符串等基础数据类型,请问如何在SQLAlchemy中实现该功能?

PostgreSQL示例代码

SELECT DISTINCT
    seller.title, array_agg(product), COUNT(product.id)
FROM seller_product
    INNER JOIN seller ON seller.ozon_id = seller_product.id_seller 
    INNER JOIN product ON product.ozon_id = seller_product.id_product 
WHERE start_id = 36
GROUP BY seller.title ORDER BY COUNT(product.id) DESC

我尝试的Python代码

slct_stmt_now = select(Seller, func.array_agg(Product.__table__), func.count(Product.id)).distinct().select_from(seller_product)
slct_stmt_now = slct_stmt_now.join(Seller, Seller.ozon_id == seller_product.columns["id_seller"]).join(Product, Product.ozon_id == seller_product.columns["id_product"]).where(seller_product.columns["start_id"] == LAST_START_ID).group_by(Seller)
now_data_txt = session.execute(slct_stmt_now.order_by(func.count(Product.id).desc())).all()
解决方案

在SQLAlchemy中实现PostgreSQL的array_agg聚合整个行对象,按以下方式调整代码即可:

  • 替换聚合对象为实体而非表结构
    不要传入Product.__table__,直接使用Product实体,SQLAlchemy会自动将其解析为对应表的行记录,聚合部分改为func.array_agg(Product)。

  • 移除冗余的distinct()
    原生SQL中的DISTINCT是多余的,GROUP BY seller.title已经会对卖家分组并合并重复行,SQLAlchemy查询中可以去掉.distinct()。

  • 对齐分组字段与原生SQL
    原生SQL按seller.title分组,代码中用group_by(Seller)会按Seller所有字段分组(若表主键为单字段可能可行,但更严谨的写法是group_by(Seller.title))。

修改后的Python代码:

slct_stmt_now = (
    select(
        Seller.title,
        func.array_agg(Product),
        func.count(Product.id)
    )
    .select_from(seller_product)
    .join(Seller, Seller.ozon_id == seller_product.columns["id_seller"])
    .join(Product, Product.ozon_id == seller_product.columns["id_product"])
    .where(seller_product.columns["start_id"] == LAST_START_ID)
    .group_by(Seller.title)
    .order_by(func.count(Product.id).desc())
)
now_data_txt = session.execute(slct_stmt_now).all()
  • 可选:聚合为JSON数组
    如果需要直接得到可序列化的JSON格式数组,可以结合PostgreSQL的row_to_json函数,将聚合结果转为JSON数组:
    slct_stmt_now = select(
        Seller.title,
        func.array_agg(func.row_to_json(Product)),
        func.count(Product.id)
    )
    # 后续连接、过滤、分组逻辑同上
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 18:45:07