row_to_json 与 sqlalchemy 的语法

Syntax for row_to_json with sqlalchemy

我想了解如何将 Postgres 的 (9.2) row_to_json 与 SqlAlchemy 一起使用。但是我还没有想出任何有效的语法。

details_foo_row_q = select([Foo.*]
    ).where(Foo.bar_id == Bar.id
).alias('details_foo_row_q')

details_foo_q = select([
    func.row_to_json(details_foo_row_q).label('details')
]).where(details_foo_row_q.c.bar_id == Bar.id
).alias('details_foo_q')

如果可能的话,我希望不必从 table 模型中输入每个字段。

从'mn'得到答案:

应该是这样的:

details_foo_row_q = select([Foo]).where(Foo.bar_id == Bar.id).alias('details_foo_row_q')

details_foo_q = select([
    func.row_to_json(literal_column(details_foo_row_q.name)).label('details')
]).select_from(details_foo_row_q).where(
    details_foo_row_q.c.bar_id == Bar.id
).alias('details_foo_q')

谢谢mn,效果很好!

您的查询生成了不正确的 SQL

SELECT row_to_json(SELECT ... FROM foo) AS details
FROM (SELECT ... FROM foo) AS details_foo_row_q

应该是

SELECT row_to_json(details_foo_row_q) AS details
FROM (SELECT ... FROM foo) AS details_foo_row_q

您需要使用 select 作为 literal_column

from sqlalchemy.sql.expression import literal_column

details_foo_q = select([
    func.row_to_json(literal_column(details_foo_row_q.name)).label('details')
]).select_from(details_foo_row_q).where(
    details_foo_row_q.c.bar_id == Bar.id
).alias('details_foo_q')

如果其他人仍在使用 row_to_json 功能,我有好消息要告诉您。 假设我们有 User class 字段 email, id 并且我们希望接收电子邮件和 ID 字段作为 JSON。 这可以使用 json_build_object 函数来完成:

from sqlalchemy import func

session.query(func.json_build_object("email", User.email, "id", User.id))

如果您使用的是最新的 SQLAlchemy,听起来也许有解决方案:

# New in version 1.4.0b2.
>>> from sqlalchemy import table, column, func, select
>>> a = table( "a", column("id"), column("x"), column("y"))
>>> stmt = select(func.row_to_json(a.table_valued()))
>>> print(stmt)
SELECT row_to_json(a) AS row_to_json_1
FROM a

https://docs.sqlalchemy.org/en/14/dialects/postgresql.html#table-types-passed-to-functions