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

Функция deferred

Функция deferred помечает столбец модели как отложенный. Такой столбец не загружается из базы данных сразу при выборке объекта, а подгружается только при первом обращении к нему. Первым параметром передаётся столбец модели, который нужно сделать отложенным. Вторым необязательным параметром передаётся группа загрузки group, позволяющая откладывать сразу несколько столбцов. Третьим необязательным параметром передаётся флаг raiseload, который запрещает обращение к столбцу до его явной загрузки.

Синтаксис

deferred(column, [group], [raiseload])

Пример

Давайте создадим модель Article с отложенным столбцом text:

from sqlalchemy import create_engine, String, Text from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, deferred, Session class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(100)) text: Mapped[str] = deferred(mapped_column(Text)) engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: article = Article(title='article 1', text='long text content') session.add(article) session.commit() res = session.get(Article, 1) print(res.title)

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

"article 1"

Пример

Давайте посмотрим, какой SQL-запрос выполняется при загрузке объекта с отложенным столбцом:

from sqlalchemy import create_engine, String, Text from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, deferred, Session class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(100)) text: Mapped[str] = deferred(mapped_column(Text)) engine = create_engine('sqlite:///:memory:', echo=True) Base.metadata.create_all(engine) with Session(engine) as session: article = Article(title='article 1', text='long text content') session.add(article) session.commit() res = session.get(Article, 1) print(res.title)

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

SELECT articles.id AS articles_id, articles.title AS articles_title FROM articles WHERE articles.id = ?

Как видно из запроса, столбец text не был выбран при загрузке объекта. Он будет загружен отдельным запросом при первом обращении к атрибуту.

Пример

Давайте обратимся к отложенному столбцу и посмотрим, какой запрос выполнится при этом:

from sqlalchemy import create_engine, String, Text from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, deferred, Session class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(100)) text: Mapped[str] = deferred(mapped_column(Text)) engine = create_engine('sqlite:///:memory:', echo=True) Base.metadata.create_all(engine) with Session(engine) as session: article = Article(title='article 1', text='long text content') session.add(article) session.commit() res = session.get(Article, 1) print(res.text)

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

SELECT articles.text AS articles_text FROM articles WHERE articles.id = ?

При обращении к атрибуту text SQLAlchemy выполнил дополнительный запрос для его загрузки.

Пример

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

from sqlalchemy import create_engine, String, Text, Integer from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, deferred, Session class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(100)) text: Mapped[str] = deferred(mapped_column(Text), group='content') num: Mapped[int] = deferred(mapped_column(Integer), group='content') engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: article = Article(title='article 1', text='long text', num=10) session.add(article) session.commit() res = session.get(Article, 1) print(res.title)

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

"article 1"

Пример

Давайте загрузим отложенную группу столбцов явно с помощью опции undefer_group:

from sqlalchemy import create_engine, String, Text, Integer from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, deferred, Session from sqlalchemy.orm import undefer_group class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] = mapped_column(String(100)) text: Mapped[str] = deferred(mapped_column(Text), group='content') num: Mapped[int] = deferred(mapped_column(Integer), group='content') engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: article = Article(title='article 1', text='long text', num=10) session.add(article) session.commit() res = session.get(Article, 1, options=[undefer_group('content')]) print(res.text, res.num)

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

"long text 10"

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

  • функцию column_property,
    которая добавляет вычисляемый столбец в модель
  • функцию query_expression,
    которая добавляет выражение запроса в модель
  • функцию composite,
    которая объединяет несколько столбцов в один атрибут
  • функцию mapped_column,
    которая настраивает столбец модели
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить