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

Метод options класса Query

Метод options класса Query позволяет указать одну или несколько опций загрузки, которые влияют на то, как SQLAlchemy будет извлекать объекты из базы данных. Первым параметром метод принимает одну или несколько опций загрузки, таких как joinedload, selectinload, lazyload, raiseload и других. Возвращается новый объект Query с примененными опциями.

Синтаксис

query.options(*options)

Пример

Давайте создадим модель Article и применим опцию joinedload для загрузки связанных данных одним запросом:

from sqlalchemy import create_engine, ForeignKey, String from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, Session, joinedload class Base(DeclarativeBase): pass class User(Base): __tablename__ = 'users' id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(String(50)) articles: Mapped[list['Article']] = relationship(back_populates='author') class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(100)) user_id: Mapped[int] = mapped_column(ForeignKey('users.id')) author: Mapped['User'] = relationship(back_populates='articles') engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: user = User(name='user') article = Article(title='article', author=user) session.add_all([user, article]) session.commit() res = session.query(Article).options(joinedload(Article.author)).all() print(res[0].author.name)

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

"user"

Пример

Давайте применим опцию raiseload, чтобы запретить ленивую загрузку и выбросить исключение при обращении к незагруженному атрибуту:

<+python+> from sqlalchemy import create_engine, ForeignKey, String from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, Session, raiseload from sqlalchemy.exc import InvalidRequestError class Base(DeclarativeBase): pass class User(Base): __tablename__ = 'users' id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(String(50)) articles: Mapped[list['Article']] = relationship(back_populates='author') class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(100)) user_id: Mapped[int] = mapped_column(ForeignKey('users.id')) author: Mapped['User'] = relationship(back_populates='articles') engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: user = User(name='user') article = Article(title='article', author=user) session.add_all([user, article]) session.commit() res = session.query(Article).options(raiseload(Article.author)).first() try: print(res.author.name) except InvalidRequestError as e: print('InvalidRequestError') <-python+>

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

"InvalidRequestError"

Пример

Давайте применим сразу несколько опций: загрузим связанные статьи через selectinload и запретим ленивую загрузку для остальных связей:

<+python+> from sqlalchemy import create_engine, ForeignKey, String from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, Session, selectinload, raiseload class Base(DeclarativeBase): pass class User(Base): __tablename__ = 'users' id: Mapped[int] = mapped_column(primary_key=True) name: Mapped[str] = mapped_column(String(50)) articles: Mapped[list['Article']] = relationship(back_populates='author') class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(100)) user_id: Mapped[int] = mapped_column(ForeignKey('users.id')) author: Mapped['User'] = relationship(back_populates='articles') engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: user = User(name='user') article = Article(title='article', author=user) session.add_all([user, article]) session.commit() res = session.query(User).options(selectinload(User.articles), raiseload('*')).all() print(len(res[0].articles)) <-python+>

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

"1"

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

  • класс Query,
    который представляет собой интерфейс запроса к базе данных
  • метод enable_eagerloads,
    который управляет автоматической жадной загрузкой связей
  • метод populate_existing,
    который обновляет объекты в сессии актуальными данными
  • метод all,
    который возвращает все результаты запроса в виде списка
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить