sqlalchemy使用INTERSECT和UNNEST

时间:2016-11-01 18:25:09

标签: python sql postgresql orm sqlalchemy

我试图将原始SQL翻译成sqlalchemy core / 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')

1 个答案:

答案 0 :(得分:2)

在子查询中引用封闭查询的表是correlation的过程,SQLAlchemy会尝试自动执行此过程。在这种情况下,我认为它不太有用,因为你的INTERSECT查询是一个“可选择的”,而不是标量值,SQLAlchemy试图将其放入FROM列表而不是SELECT列表中{1}}列表。

解决方案是双重的。我们需要让SQLAlchemy通过应用INTERSECTSELECT列表放在label列表中,并使其与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"