РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
165 of 711 menu

Функция query_expression

Функция query_expression создает дескриптор на уровне класса модели. Атрибут, объявленный через query_expression, доступен только для чтения и не хранится в таблице модели. Его значение вычисляется отдельным SQL-запросом в момент обращения к атрибуту у загруженного объекта. Первым параметром функция принимает функцию или лямбду, которая возвращает скалярный SQL-запрос. Вторым необязательным параметром можно передать функцию загрузки, например joinedload, чтобы значение подгружалось сразу вместе с объектом.

Синтаксис

query_expression(fn, [load_fn])

Пример

Давайте создадим модель Article и добавим в неё атрибут title_upper через query_expression, который вернет заголовок в верхнем регистре:

from sqlalchemy import create_engine, select, func from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session, query_expression class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] text: Mapped[str] status: Mapped[str] num: Mapped[int] title_upper = query_expression() engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: session.add(Article(title='article', text='some text', status='draft', num=1)) session.commit() stmt = select(Article).options( query_expression(Article.title_upper, func.upper(Article.title)) ) art = session.scalars(stmt).one() print(art.title_upper)

Результат выполнения кода:

"ARTICLE"

Пример

Давайте посчитаем количество статей с тем же статусом через подзапрос и выведем результат для загруженного объекта:

from sqlalchemy import create_engine, select, func from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session, query_expression class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] text: Mapped[str] status: Mapped[str] num: Mapped[int] same_status_count = query_expression() engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: session.add_all([ Article(title='article 1', text='text 1', status='draft', num=1), Article(title='article 2', text='text 2', status='draft', num=2), Article(title='article 3', text='text 3', status='published', num=3), ]) session.commit() subq = ( select(func.count(Article.id)) .where(Article.status == Article.status) .correlate(Article) .scalar_subquery() ) stmt = select(Article).options( query_expression(Article.same_status_count, subq) ) for art in session.scalars(stmt): print(art.title, art.same_status_count)

Результат выполнения кода:

"article 1 2" "article 2 2" "article 3 1"

Смотрите также

  • функцию column_property,
    которая создает вычисляемый на уровне SQL атрибут модели
  • функцию deferred,
    которая откладывает загрузку колонки до обращения
  • класс DeclarativeBase,
    который является базой для декларативных моделей
  • функцию mapped_column,
    которая описывает колонку таблицы в модели
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить