【问题标题】:Can we make correlated queries with SQLAlchemy我们可以使用 SQLAlchemy 进行相关查询吗
【发布时间】:2016-11-02 19:07:08
【问题描述】:

我正在尝试将此 SQL 查询转换为 Flask-SQLAlchemy 调用:

SELECT *
FROM "ENVOI"
WHERE "ID_ENVOI" IN (SELECT d."ID_ENVOI"
                     FROM "DECLANCHEMENT" d
                     WHERE d."STATUS" = 0
                                    AND d."DATE" = (SELECT max("DECLANCHEMENT"."DATE")
                                    FROM "DECLANCHEMENT"
                                    WHERE "DECLANCHEMENT"."ID_ENVOI" = d."ID_ENVOI"))

如您所见,它使用子查询,最重要的是,其中一个子查询是相关查询(它使用在外部查询中定义的d 表)。

我知道如何使用带有subquery() 函数的子查询,但是我找不到有关使用 SQLAlchemy 进行相关查询的文档。你知道怎么做吗?

【问题讨论】:

  • “相关子查询”是一个比“同步子查询”更常见的术语。您可以在tutorial 中找到示例。

标签: python postgresql sqlalchemy


【解决方案1】:

是的,我们可以。

看看下面的例子(尤其是correlate方法调用):

from sqlalchemy import select, func, table, Column, Integer

table1 = table('table1', Column('col', Integer))
table2 = table('table2', Column('col', Integer))


subquery = select(
    [func.if_(table1.c.col == 1, table2.c.col, None)]
).correlate(table1)

query = (
    select([table1.c.col,
            subquery.label('subquery')])
    .select_from(table1)
)

if __name__ == '__main__':
    print(query)

将导致以下查询

SELECT table1.col, (SELECT if(table1.col = :col_1, table2.col, NULL) AS if_1 
FROM table2) AS subquery 
FROM table1

如您所见,如果您在select 上调用correlate,则给定的Table 将不会添加到它的FROM 子句中。 即使您直接指定 select_from,您也必须这样做,因为 SQLAlchemy 很乐意添加它在列中找到的任何表。

【讨论】:

    【解决方案2】:

    根据 univerio 评论中的链接,我为我的请求完成了以下代码:

    Declch = db.aliased(Declanchement)
    
    maxdate_sub = db.select([db.func.max(Declanchement.date)])\
                    .where(Declanchement.id_envoi == Declch.id_envoi)
    
    decs_sub = db.session.query(Declch.id_envoi)\
                .filter(Declch.status == SMS_EN_ATTENTE)\
                .filter(Declch.date < since)\
                .filter(Declch.date == maxdate_sub).subquery()
    
    envs = Envoi.query.filter(Envoi.id_envoi.in_(decs_sub)).all()
    

    【讨论】:

    • 如果子查询返回多行,我将如何在主查询中使用 maxdate_sub?
    • 已经好几年了,这些天我不玩了,但我猜你会使用像in_这样的函数(在这种情况下见decs_sub
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多