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

Метод yield_per

Метод yield_per класса Query выполняет SQL-запрос и возвращает итератор, который загружает объекты порциями указанного размера. Метод принимает один параметр count - количество строк, извлекаемых из базы данных за один раз. Это позволяет существенно снизить потребление памяти при обработке больших наборов данных.

Метод особенно полезен в сочетании с итерацией по результатам запроса, когда нет необходимости загружать все объекты в память одновременно. Следует учитывать, что при использовании yield_per коллекции связей, загружаемые через joined eager loading, могут работать некорректно.

Синтаксис

Query.yield_per(count)

Параметр count задает размер порции загружаемых строк. Если передать значение 0 или отрицательное число, все строки будут загружены сразу.

Пример

Давайте создадим модель Article и продемонстрируем порционную загрузку объектов через yield_per:

from sqlalchemy import create_engine, String, Integer from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, 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] = mapped_column(String(500)) status: Mapped[str] = mapped_column(String(50)) num: Mapped[int] = mapped_column(Integer)

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

from sqlalchemy import create_engine from sqlalchemy.orm import Session from models import Base, Article engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: for i in range(1, 6): session.add(Article( title=f'article {i}', text=f'text {i}', status='published', num=i )) session.commit() with Session(engine) as session: query = session.query(Article).yield_per(2) for article in query: print(article.title)

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

"article 1" "article 2" "article 3" "article 4" "article 5"

Пример

Давайте сравним поведение обычного запроса и запроса с yield_per, выведя количество объектов, загруженных за раз:

<+python+> from sqlalchemy import create_engine from sqlalchemy.orm import Session from models import Base, Article engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: for i in range(1, 8): session.add(Article( title=f'article {i}', text=f'text {i}', status='draft', num=i )) session.commit() with Session(engine) as session: query = session.query(Article).yield_per(3) batch = [] for article in query: batch.append(article.title) if len(batch) == 3: print(f'Batch loaded: {batch}') batch = [] if batch: print(f'Batch loaded: {batch}') <-python+>

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

"Batch loaded: ['article 1', 'article 2', 'article 3']" "Batch loaded: ['article 4', 'article 5', 'article 6']" "Batch loaded: ['article 7']"

Пример

Давайте применим yield_per вместе с фильтрацией и сортировкой для обработки отфильтрованного набора данных:

<+python+> from sqlalchemy import create_engine from sqlalchemy.orm import Session from models import Base, Article engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: for i in range(1, 6): session.add(Article( title=f'article {i}', text=f'text {i}', status='published' if i % 2 == 0 else 'draft', num=i )) session.commit() with Session(engine) as session: query = ( session.query(Article) .filter(Article.status == 'published') .order_by(Article.num) .yield_per(1) ) for article in query: print(f'{article.title} - {article.status}') <-python+>

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

"article 2 - published" "article 4 - published"

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

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