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

Метод yield_per

Метод yield_per класса Result возвращает итератор, который выдаёт строки результата пакетами заданного размера. Это позволяет обрабатывать большие выборки без загрузки всех строк в память сразу. Первым параметром передаётся целое число num_rows - размер пакета. Второй необязательный параметр max_row_buffer задаёт максимальный размер буфера.

Метод удобен при чтении миллионов записей: драйвер базы данных отдаёт строки порциями, а SQLAlchemy не кеширует их целиком. Для ORM-запросов метод также доступен через объект Result, полученный из Session.execute.

Синтаксис

Result.yield_per(num_rows, [max_row_buffer])

Пример

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

from sqlalchemy import create_engine, text engine = create_engine('sqlite:///:memory:') with engine.connect() as conn: conn.execute(text('CREATE TABLE articles (id INTEGER, title TEXT)')) conn.execute(text("INSERT INTO articles (id, title) VALUES (1, 'article 1')")) conn.execute(text("INSERT INTO articles (id, title) VALUES (2, 'article 2')")) conn.execute(text("INSERT INTO articles (id, title) VALUES (3, 'article 3')")) res = conn.execute(text('SELECT id, title FROM articles ORDER BY id')) for row in res.yield_per(2): print(row)

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

(1, 'article 1') (2, 'article 2') (3, 'article 3')

Пример

Давайте используем yield_per вместе с ORM-моделью и выведем заголовки статей:

from sqlalchemy import create_engine, String 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(50))
from sqlalchemy import create_engine, select 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: session.add_all([ Article(id=1, title='article 1'), Article(id=2, title='article 2'), Article(id=3, title='article 3'), ]) session.commit() res = session.execute(select(Article).order_by(Article.id)) for article in res.scalars().yield_per(2): print(article.title)

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

"article 1" "article 2" "article 3"

Пример

Давайте убедимся, что yield_per действительно отдаёт строки по одной, а не списком:

from sqlalchemy import create_engine, text engine = create_engine('sqlite:///:memory:') with engine.connect() as conn: conn.execute(text('CREATE TABLE articles (id INTEGER, title TEXT)')) conn.execute(text("INSERT INTO articles (id, title) VALUES (1, 'article')")) conn.execute(text("INSERT INTO articles (id, title) VALUES (2, 'user')")) res = conn.execute(text('SELECT id, title FROM articles')) iterator = res.yield_per(1) print(type(iterator).__name__) print(next(iterator)) print(next(iterator))

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

"ChunkedIteratorResult" (1, 'article') (2, 'user')

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

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