使用SqlAlchemy表达式语言作为列的子查询

使用SqlAlchemy表达式语言作为列的子查询,sqlalchemy,Sqlalchemy,注意,我使用的不是ORM,而是表达式 我正在尝试执行一个查询,该查询以列的形式返回Postgres json_agg。 SQL查询如下所示: 选择 表1.1, 表1.1名称, 选择json\u aggjson\u build\u对象 名称 表2.1名称 作为foobar 哪里 表1.id=1; 当我尝试执行以下操作时,它将查询转换为两个,其中第一个是子查询 选择 [ 表1, 挑选[ func.json_agg func.json\u build\u对象 textname, 表2.c.名称 ] ]

注意,我使用的不是ORM,而是表达式

我正在尝试执行一个查询,该查询以列的形式返回Postgres json_agg。 SQL查询如下所示:

选择 表1.1, 表1.1名称, 选择json\u aggjson\u build\u对象 名称 表2.1名称 作为foobar 哪里 表1.id=1; 当我尝试执行以下操作时,它将查询转换为两个,其中第一个是子查询

选择 [ 表1, 挑选[ func.json_agg func.json\u build\u对象 textname, 表2.c.名称 ] ] .其中表1.c.id==1 正如我刚才在stackoverflow中所写的那样,上面的内容在语法上可能是错误的,以说明我的观点


如何把它变成一个选择。。。作为column\u name子查询?

您可以使用下面的查询来完全满足您的要求:

query = (
    select(
        table1,
        select(
            func.json_agg(
                func.json_build_object("name", table2.c.name)
            ).label("foobar")
        ).scalar_subquery(),  # <- THIS IS the key
    )
    .where(table1.c.id == 1)
)
query = (
    select([
        table1,
        func.json_agg(
            func.json_build_object("name", table2.c.name)  # NOTE: `text("name")` will fail in this example (ambigous between table2.name and table1.name, you simply want a string i assume
        ).label("foobar")
    ])
    .where(table1.c.id == 1)
    .join(table2)  # NOTE: i guess you want to join here, else you will get all entries from table2 in the "foobar"
    .group_by(table1)  # !!! <- IMPORTANT to allow the agg function to work
)
这将生成类似于以下内容的SQL:

SELECT table1.id,
       table1.name,
       json_agg(json_build_object('name', table2.name)) AS foobar
FROM table1
JOIN table2 ON table1.id = table2.table1_id
WHERE table1.id = 1
GROUP BY table1.id,
         table1.name

请查看最近的Q/A是否对您有帮助:。一个区别可能是您似乎在引用sqlalchemy 1.3,而参考答案使用1.4语法。不幸的是,不是这样。我就是这样开始的,但是json_aggs需要在WHERE之前作为列作为子查询,因为无法联接表2