我正在尝试将原始 SQL 转换为 sqlalchemy 核心/orm,但我遇到了一些困难。这是 SQL:
SELECT
(SELECT UNNEST(MyTable.my_array_column)
INTERSECT
SELECT UNNEST(ARRAY['VAL1', 'VAL2']::varchar[])) AS matched
FROM
MyTable
WHERE
my_array_column && ARRAY['VAL1', 'VAL2']::varchar[];
以下查询为我提供了一个 FROM
子句,我在嵌套的 SELECT
中不需要它:
matched = select([func.unnest(MyTable.my_array_column)]).intersect(select([func.unnest('VAL1', 'VAL2')]))
# SELECT unnest(MyTable.my_array_colum) AS unnest_1
# FROM MyTable INTERSECT SELECT unnest(%(unnest_3)s, %(unnest_4)s) AS unnest_2
如何告诉 select
不包含 FROM
子句?请注意,func.unnest()
只接受一列。所以我不能使用 func.unnest('my_array_column')
。
最佳答案
在子查询中引用一个封闭查询的表是correlation的过程,SQLAlchemy 尝试自动执行。在这种情况下,它不太有效,我相信,因为您的 INTERSECT
查询是一个“可选择的”,而不是标量值,SQLAlchemy 试图将其放入 FROM
列表而不是 SELECT
列表。
解决方案有两个。我们需要通过应用 label
使 SQLAlchemy 将 INTERSECT
查询放入 SELECT
列表中,并使其关联 MyTable
正确:
select([
select([func.unnest(MyTable.my_array_column)]).correlate(MyTable)
.intersect(select([func.unnest('VAL1', 'VAL2')]))
.label("matched")
]).select_from(MyTable)
# SELECT (SELECT unnest("MyTable".my_array_column) AS unnest_1 INTERSECT SELECT unnest(%(unnest_3)s, %(unnest_4)s) AS unnest_2) AS matched
# FROM "MyTable"
关于python - 使用 INTERSECT 和 UNNEST 的 sqlalchemy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40366275/