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

Значение lazy select

Значение lazy со строкой 'select' задает стратегию отложенной загрузки связанных объектов в SQLAlchemy. Это поведение используется по умолчанию для связей relationship. Связанные строки не загружаются вместе с родительским объектом. Вместо этого при первом обращении к атрибуту связи SQLAlchemy отправляет отдельный SELECT запрос и только затем возвращает результат. Значение lazy принимает строку 'select' и передается в параметр lazy функции relationship. Такой подход экономит память при работе с большим количеством родителей, если связанные объекты нужны не всегда.

Синтаксис

relationship(..., lazy='select')

Пример

Давайте создадим две модели, связанные отношением один-ко-многим, и укажем для связи стратегию lazy со значением 'select':

from sqlalchemy import create_engine, ForeignKey from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, Session class Base(DeclarativeBase): pass class User(Base): __tablename__ = 'users' id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] articles: Mapped[list['Article']] = relationship(lazy='select') 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] user_id: Mapped[int] = mapped_column(ForeignKey('users.id')) engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: user = User(name='user') user.articles = [ Article(title='article 1', text='text 1', status='new', num=1), Article(title='article 2', text='text 2', status='new', num=2), ] session.add(user) session.commit()

Теперь при обращении к атрибуту articles SQLAlchemy выполнит отдельный запрос только в этот момент:

from sqlalchemy import create_engine from sqlalchemy.orm import Session from models import User engine = create_engine('sqlite:///:memory:') with Session(engine) as session: user = session.get(User, 1) print('before access') titles = [a.title for a in user.articles] print(titles)

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

"before access" ['article 1', 'article 2']

Пример

Давайте посмотрим, какие SQL-запросы отправляются при стратегии lazy со значением 'select'. Первый запрос загружает родителя, второй - связанные строки:

from sqlalchemy import create_engine from sqlalchemy.orm import Session from models import User engine = create_engine('sqlite:///:memory:', echo=True) with Session(engine) as session: user = session.get(User, 1) titles = [a.title for a in user.articles] print(titles)

Итоговый SQL запрос для связанных строк:

SELECT articles.id AS articles_id, articles.title AS articles_title, articles.text AS articles_text, articles.status AS articles_status, articles.num AS articles_num, articles.user_id AS articles_user_id FROM articles WHERE ? = articles.user_id

Пример

Значение lazy можно указать не только в модели, но и переопределить на уровне запроса методом options:

from sqlalchemy import create_engine from sqlalchemy.orm import Session, selectinload from models import User from sqlalchemy import select engine = create_engine('sqlite:///:memory:') with Session(engine) as session: stmt = select(User).options(selectinload(User.articles)) user = session.scalars(stmt).first() titles = [a.title for a in user.articles] print(titles)

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

['article 1', 'article 2']

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

  • функцию relationship,
    которая настраивает связи между моделями
  • значение lazy selectin,
    которое загружает связи отдельным IN-запросом
  • значение lazy joined,
    которое загружает связи через JOIN
  • значение lazyload,
    которое включает отложенную загрузку явно
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить