Функция noload
Функция noload отключает загрузку указанной связи
при выполнении запроса. Она принимает один обязательный
параметр - атрибут связи, который нужно не загружать.
Этот параметр передаётся в виде аргумента в функцию
noload. При использовании noload связанные
объекты не загружаются из базы данных, а вместо этого
для них устанавливается значение None или пустая
коллекция. Это полезно, когда связь не нужна в данном
запросе и её загрузка приведёт к лишним SQL-запросам.
Синтаксис
from sqlalchemy.orm import noload
noload(attribute)
Пример
Давайте создадим модель статьи со связью на пользователя
и применим noload для отключения загрузки этой связи:
from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, Session, noload
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(Article).options(noload(Article.user)).first()
print(res.user)
Результат выполнения кода:
None
Пример
Давайте рассмотрим разницу между обычной загрузкой
связи и загрузкой с noload на примере
коллекции статей пользователя:
from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship, Session, noload
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(noload(User.articles)).first()
print(res.articles)
Результат выполнения кода:
[]
Смотрите также
-
функцию
lazyload,
которая включает ленивую загрузку связи -
функцию
joinedload,
которая загружает связь через JOIN -
функцию
selectinload,
которая загружает связь отдельным SELECT -
функцию
relationship,
которая настраивает связь между моделями