Почему результат sqlalchemy диктует игнорирование столбцов text ()?

#python #postgresql #sqlalchemy

Вопрос:

Я пытаюсь использовать новый синтаксис sqlalchemy 1.4 select (), но при выполнении этого простого запроса в результате не отображается столбец «график», но список результатов включает его.

 import sqlalchemy as sa
from source.Models import Quadrant, Graph

engine = sa.create_engine("postgresql://blahblahblah")

dbsession = sa.orm.Session(engine)

stmt = sa.select(
    Quadrant.id,
    sa.text("jsonb_agg(graph.data order by graph.id) as graphs")
).outerjoin(
    Graph, Quadrant.id == Graph.quadrant_id
).group_by(
    Quadrant.id
)

with dbsession.begin():
    res = dbsession.execute(stmt)
    for r in res:
        print(r.keys())   # -> ['id'] **no graphs here!**
        print(list(r))    # -> [0, {aggregated data}]
        print(r[1])       # -> {aggregated data}
 

Есть ли способ, чтобы результат в виде диктанта включал текстовый столбец?

Я не заинтересован в агрегировании результата в python: я хочу агрегировать его в postgresql.

Комментарии:

1. Также вы должны иметь возможность использовать array_agg функцию вместо использования text() .

2. метод text() не имеет атрибута «метка». ну, на самом деле проблема была в функции jsonb_agg . Я использовал array_agg, чтобы упростить задачу.

Ответ №1:

Используйте literal_column вместо text , если вы хотите использовать фрагмент текста:

 sa.literal_column("jsonb_agg(graph.data order by graph.id)").label("graph")
 

Вы также можете создать выражение с помощью конструкций SQLA:

 from sqlalchemy.dialects.postgresql import aggregate_order_by

sa.func.jsonb_agg(aggregate_order_by(Graph.data, Graph.id)).label('graph')