Как выполнить подзапрос в SQLAlchemy?

Пользователь

от brook , в категории: Python , год назад

Как выполнить подзапрос в SQLAlchemy?

Facebook Vk Ok Twitter LinkedIn Telegram Whatsapp

2 ответа

Пользователь

от ottilie.farrell , год назад

@brook 

В SQLAlchemy подзапросы могут быть выполнены с использованием методов session.query() и select(). Например, для выполнения подзапроса в session.query(), можно использовать метод subquery():

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from sqlalchemy.orm import subqueryload

sub_query = session.query(OrderItem.product_id, func.count(OrderItem.id).label('num_orders')).group_by(OrderItem.product_id).subquery()

query = session.query(Product).outerjoin(
    sub_query,
    Product.id == sub_query.c.product_id,
).options(subqueryload(Product.order_items))

for product in query:
    print(product.name, product.order_items[0].num_orders if product.order_items else 0)


Этот подзапрос группирует товары по product_id и считает количество заказов для каждого товара. Затем этот подзапрос присоединяется к основному запросу через оператор соединения и выполняется запрос subqueryload для загрузки связанных объектов OrderItem.

Пользователь

от kaleigh , месяц назад

@brook 

Есть несколько способов выполнить подзапрос в SQLAlchemy. Ниже приведены два примера:

  1. Использование метода subquery() и CTE (Common Table Expression):
1
2
3
4
5
6
7
from sqlalchemy import func, select, subquery

subq = select([func.count()]).select_from(Table1).where(Table1.col1 == Table2.col2).scalar_subquery()

q = select([Table2, subq.label('count_col')]).where(Table2.col3 > subq)

result = engine.execute(q).fetchall()


  1. Использование подзапроса как встроенного запроса:
1
2
3
4
5
6
from sqlalchemy import func, select

stmt = select([Table1.col1]).where(Table1.col1 == Table2.col2).correlate(Table2).scalar_subquery()
q = select([Table2, stmt.label('count_col')]).where(Table2.col3 > stmt)

result = engine.execute(q).fetchall()


Оба примера демонстрируют выполнение подзапроса с использованием функций SQLAlchemy.