使用PostgreSQL / SqlAlchemy选择ARRAY的第一项

时间:2017-09-23 02:04:48

标签: python postgresql sqlalchemy

尝试将我每天运行的一些查询移动到自动脚本中。我在Postgres中有一个如下所示:

SELECT regexp_split_to_array(col1, "|")[1] AS item, COUNT(*) AS itemcount FROM Tabel1 GROUP BY item ORDER BY itemcount

在SqlAlchemy中我有这个:

session.query((func.regexp_split_to_array(model.table1.col1, "|")[1]).label("item"), func.count().label("itemcount")).group_by("item").order_by("itemcount")

Python不能“get_item”,因为它实际上不是一个集合。我查看了文档并且似乎找不到能够让我在没有使用execute运行原始SQL的情况下执行此操作的东西(我可以做和工作,但是下次正在寻找解决方案)。

1 个答案:

答案 0 :(得分:4)

SQLAlchemy确实支持使用[...]建立索引。如果您声明的类型必须是postgresql.ARRAY类型的列,那么它可以工作:

table2 = Table("table2", meta, Column("col1", postgresql.ARRAY(String)))
q = session.query(table2.c.col1[1])
print(q.statement.compile(dialect=postgresql.dialect()))
# SELECT table2.col1[%(col1_1)s] AS anon_1 
# FROM table2

您的代码不起作用的原因是SQLAlchemy不知道func.regexp_split_to_array(...)返回一个数组,因为func.foo生成一个通用函数以方便起见。为了使它工作,我们需要通过指定type_参数来确保SQLAlchemy知道函数的返回类型:

q = session.query(func.regexp_split_to_array(table1.c.col1, "|", type_=postgresql.ARRAY(String))[1].label("item"))
print(q.statement.compile(dialect=postgresql.dialect()))
# SELECT (regexp_split_to_array(table1.col1, %(regexp_split_to_array_1)s))[%(regexp_split_to_array_2)s] AS item 
# FROM table1