gpt4 book ai didi

python - 在 SQLAlchemy 连接子句中使用函数输出

转载 作者:行者123 更新时间:2023-11-29 13:12:31 24 4
gpt4 key购买 nike

我正在尝试将相当短的 SQL 翻译成 sqlAlchemy ORM 查询。 SQL 使用 Postgres 的 generate_series 生成一组日期,我的目标是生成一组按其中一列分类的时间序列数组。

表格(简化)非常简单:

counts:
-----------------
count (Integer)
day (Date)
placeID (foreign key related to places)

"counts_pkey" PRIMARY KEY (day, placeID)

places:
-----------------
id
name (varchar)

我所追求的输出是每个地点的计数时间序列,其中包括一天未报告计数时的空值。例如,这对应于四天的系列:

    array_agg    |    name
-----------------+-------------------
{NULL,0,7,NULL} | A Place
{NULL,1,NULL,2} | Some other place
{5,NULL,3,NULL} | Yet another

我可以通过对日期范围和地点进行CROSS JOIN并将其与计数相结合来相当轻松地做到这一点:

SELECT array_agg(counts.count), places.name 
FROM generate_series('2018-11-01', '2018-11-04', interval '1 days') as day
CROSS JOIN places
LEFT OUTER JOIN counts on counts.day = day.day AND counts.PlaceID = places.id
GROUP BY places.name;

我似乎无法弄清楚如何让 SQLAlchemy 执行此操作。经过大量挖掘,我发现了一个 old google groups thread这几乎可以导致这个:

date_list = select([column('generate_series')])\
.select_from(func.generate_series(backthen, today, '1 day'))\
.alias('date_list')

time_series = db.session.query(Place.name, func.array_agg(Count.count))\
.select_from(date_list)\
.outerjoin(Count, (Count.day == date_list.c.generate_series) & (Count.placeID == Place.id ))\
.group_by(Place.name)

这会为时间序列创建一个子选择,但会产生数据库错误:

There is an entry for table "places", but it cannot be referenced from this part of the query.

所以我的问题是:您将如何在 sqlalchemy 中执行此操作。此外,我对这很困难的想法持开放态度,因为我使用 SQL 的方法是愚蠢的。

最佳答案

问题是给定的查询结构 SQLAlchemy 产生了一个查询

SELECT ...
FROM places,
(...) AS date_list LEFT OUTER JOIN count ON ... AND count."placeID" = places.id
...

有 2 个 FROM 列表项:places 和连接。项目不能相互引用1,因此错误是由于 ON 子句中的 places.id 造成的。

SQLAlchemy 不支持显式CROSS JOIN,但另一方面,CROSS JOIN 等同于 INNER JOIN ON (TRUE) .您还可以省略将函数表达式包装在子查询中并按原样使用 giving it an alias :

date_list = func.generate_series(backthen, today, '1 day').alias('gen_day')

time_series = session.query(Place.name, func.array_agg(Count.count))\
.join(date_list, true())\
.outerjoin(Count, (Count.day == column('gen_day')) &
(Count.placeID == Place.id ))\
.group_by(Place.name)

1:函数调用FROM项除外,或使用LATERAL

关于python - 在 SQLAlchemy 连接子句中使用函数输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53137019/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com