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

Функция raiseload

Функция raiseload запрещает ленивую загрузку связанных объектов. Она применяется в опциях загрузки запроса и заставляет SQLAlchemy выбрасывать исключение InvalidRequestError, если код попытается обратиться к отношению, которое не было загружено заранее. Первым параметром функция принимает атрибут отношения или строку с именем отношения. Вторым необязательным параметром передается флаг sql_only, который ограничивает проверку только SQL-запросами.

Синтаксис

raiseload(attr, [sql_only])

Пример

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

from sqlalchemy import create_engine, ForeignKey from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, Session from sqlalchemy.orm import raiseload 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(back_populates='user') 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')) user: 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', user=user) session.add_all([user, article]) session.commit() res = session.query(User).options(raiseload(User.articles)).first() print(res.name) try: print(res.articles) except Exception as e: print(type(e).__name__)

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

"user" "InvalidRequestError"

Пример

Давайте запретим ленивую загрузку через строковое имя отношения:

from sqlalchemy import create_engine, ForeignKey from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, Session from sqlalchemy.orm import raiseload 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(back_populates='user') 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')) user: 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', user=user) session.add_all([user, article]) session.commit() res = session.query(User).options(raiseload('articles')).first() print(res.name) try: print(res.articles) except Exception as e: print(type(e).__name__)

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

"user" "InvalidRequestError"

Пример

Давайте используем параметр sql_only, чтобы запретить только SQL-загрузку, но разрешить загрузку из уже загруженных объектов:

from sqlalchemy import create_engine, ForeignKey from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, Session from sqlalchemy.orm import raiseload, joinedload 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(back_populates='user') 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')) user: 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', user=user) session.add_all([user, article]) session.commit() res = session.query(User).options(joinedload(User.articles), raiseload(User.articles, sql_only=True)).first() print(res.name) print([a.title for a in res.articles])

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

"user" ['article']

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

  • функцию joinedload,
    которая загружает отношение через JOIN
  • функцию selectinload,
    которая загружает отношение отдельным SELECT
  • функцию lazyload,
    которая включает ленивую загрузку отношения
  • функцию noload,
    которая отключает загрузку отношения
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить