Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
308 of 711 menu
◀ ▶

Значение lazy selectin

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

Синтаксис

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

Пример

Давайте опишем две связанные модели, где связь использует стратегию selectin:

from sqlalchemy import ForeignKey from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship class Base(DeclarativeBase): pass class User(Base): __tablename__ = 'users' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] articles: Mapped[list['Article']] = relationship(lazy='selectin') class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] user_id: Mapped[int] = mapped_column(ForeignKey('users.id'))

Теперь при загрузке пользователей SQLAlchemy одним дополнительным запросом подтянет все связанные статьи:

from sqlalchemy import create_engine, select from sqlalchemy.orm import Session from models import Base, User, Article engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: user = User(id=1, title='user') article = Article(id=1, title='article', user_id=1) session.add_all([user, article]) session.commit() res = session.scalars(select(User)).all() for u in res: print(u.title, [a.title for a in u.articles])

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

"user ['article']"

Итоговый SQL запрос:

SELECT users.id, users.title FROM users SELECT articles.user_id AS articles_user_id, articles.id AS articles_id, articles.title AS articles_title FROM articles WHERE articles.user_id IN (1)

Пример

Стратегию selectin можно переопределить на уровне отдельного запроса с помощью опции selectinload:

from sqlalchemy import create_engine, select from sqlalchemy.orm import Session, selectinload from models import Base, User, Article engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: user = User(id=1, title='user') article = Article(id=1, title='article', user_id=1) session.add_all([user, article]) session.commit() stmt = select(User).options(selectinload(User.articles)) res = session.scalars(stmt).all() for u in res: print(u.title, [a.title for a in u.articles])

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

"user ['article']"

Итоговый SQL запрос:

SELECT users.id, users.title FROM users SELECT articles.user_id AS articles_user_id, articles.id AS articles_id, articles.title AS articles_title FROM articles WHERE articles.user_id IN (1)

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

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