【问题标题】:SQLAlchemy, PostgreSQL and array_agg: How to select items from array_agg?SQLAlchemy、PostgreSQL 和 array_agg:如何从 array_agg 中选择项目?
【发布时间】:2014-06-09 07:52:02
【问题描述】:

我想在子查询中使用array_agg,然后在我的主查询中通过它的数组索引来使用聚合数据,但是,在尝试了许多不同的方法之后,我真的不知道应该怎么做完成;有人能解释一下为什么在下面的示例中我得到一系列 None 值而不是数组中的第一个类别吗?

我了解以下简化示例无需对数组 [i] 执行 SELECT 即可完成,但它将解释问题的本质:

from sqlalchemy import Integer
from sqlalchemy.dialects.postgres import ARRAY

prods = (
    session.query(
        Product.id.label('id'),
        func.array_agg(ProductCategory.id, type_=ARRAY(Integer)).label('cats'))
    .outerjoin(
        ProductCategory,
        ProductCategory.product_id == Product.id)
    .group_by(Product.id).subquery()
)

# Confirm that there's categories:
[x for x in session.query(prods) if len(x[1]) > 1][:10]
"""
Out[48]: 
[(2428, [1633667, 1633665, 1633666]),
 (2462, [1162046, 1162043, 2543783, 1162045]),
 (2573, [1633697, 1633696]),
 (2598, [2546824, 922288, 922289]),
 (2645, [2544843, 338411]),
 (2660, [1633713, 1633714, 1633712, 1633711]),
 (2686, [2547480, 466995, 466996]),
 (2748, [2546706, 2879]),
 (2785, [467074, 467073, 2545804]),
 (2806, [2545326, 686295, 686298, 686297])]
"""

# Ok now try to query to get the first category of each array:
[x for x in session.query(prods.c.cats[0].label('first_cat'))]

"""
 (None),
 (None),
 (None),
 (None),
 (None),
 (None),
 (None),
 (None),
 (None),
 (None),
 (None),
"""

【问题讨论】:

  • 您使用0 作为第一个数组元素的索引。在 Postgres 中,索引默认以1 开头。 Python 会将其翻译成0 还是一个简单的问题?

标签: python postgresql sqlalchemy


【解决方案1】:

您可能做对了所有事情,但首先获取的是空数组。在您之前的查询中,您使用了 in-python 过滤 (len(x[1]) > 1)。您可以在执行之前打印Query 表达式以确保。

您可能应该在基本查询中添加 having 子句:

from sqlalchemy import Integer
from sqlalchemy.dialects.postgresql import ARRAY

cats_agg = func.array_agg(ProductCategory.id, type_=ARRAY(Integer)).label('cats')
prods = (
    session.query(
        Product.id.label('id'),
        cats_agg,
    .outerjoin(
        ProductCategory,
        ProductCategory.product_id == Product.id)
    .group_by(Product.id)
    .having(func.array_length(cats_agg, 1) > 1)
    .subquery()
)

那么你也不需要 in-python 过滤。

【讨论】:

  • 问题只是.. 用于数组的索引错误,[1] 而不是 [0]。谢谢!
猜你喜欢
  • 1970-01-01
  • 2018-04-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-29
  • 1970-01-01
相关资源
最近更新 更多