5

I would like to figure out how to use Postgres' (9.2) row_to_json with SqlAlchemy. However I haven't been able to come up with any working syntax.

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')

I would ideally like to not to have to type out each and every field from the table model if possible.

Got the answer from 'mn':

It should be something more like this:

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')

Thank you mn, works great!

3 Answers 3

4

Your query generates an incorrect SQL

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

It should be

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

You need to use select as 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')
Sign up to request clarification or add additional context in comments.

1 Comment

it works! I guess due to the 'name' variable as well as the literal_column
2

Sounds like maybe there is a solution IFF you are using the latest 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

Comments

0

If other people still struggle with row_to_json function, I have good news for you. Let's imagine we have User class with fields email, id and we want to receive email and id fields as JSON. This can be done using json_build_object function:

from sqlalchemy import func

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.