Reputation: 8536
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!
Upvotes: 4
Views: 2301
Reputation: 805
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
Upvotes: 2
Reputation: 11
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))
Upvotes: 0
Reputation: 15090
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')
Upvotes: 3