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

Событие after_bulk_update

Событие after_bulk_update срабатывает после выполнения массового обновления записей. Такое обновление выполняется методом update у объекта Query и не проходит через обычные события before_update и after_update, которые работают только с отдельными объектами сессии. Событие after_bulk_update позволяет перехватить момент завершения массового обновления. Обработчик получает объект Update, содержащий информацию о запросе и количестве затронутых строк.

Синтаксис

from sqlalchemy import event event.listen(Query, 'after_bulk_update', fn)

Пример

Давайте создадим модель и подпишемся на событие after_bulk_update, чтобы вывести количество обновлённых строк:

from sqlalchemy import create_engine, event from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session from sqlalchemy.orm import Query class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] status: Mapped[str] engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) def after_bulk_update_handler(update_context): print('updated rows:', update_context.rowcount) event.listen(Query, 'after_bulk_update', after_bulk_update_handler) with Session(engine) as session: session.add_all([ Article(title='article 1', status='draft'), Article(title='article 2', status='draft'), Article(title='article 3', status='published'), ]) session.commit() session.query(Article).filter( Article.status == 'draft' ).update({'status': 'published'}) session.commit()

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

"updated rows: 2"

Пример

Давайте рассмотрим объект Update, который передаётся в обработчик события. У него есть атрибуты rowcount и statement:

from sqlalchemy import create_engine, event from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session from sqlalchemy.orm import Query class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] status: Mapped[str] engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) def after_bulk_update_handler(update_context): print('rowcount:', update_context.rowcount) print('statement:', update_context.statement) event.listen(Query, 'after_bulk_update', after_bulk_update_handler) with Session(engine) as session: session.add_all([ Article(title='article 1', status='draft'), Article(title='article 2', status='draft'), ]) session.commit() session.query(Article).filter( Article.status == 'draft' ).update({'status': 'published'}) session.commit()

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

"rowcount: 2" "statement: UPDATE articles SET status=? WHERE articles.status = ?"

Пример

Давайте используем event.remove, чтобы отписаться от события после первого срабатывания:

from sqlalchemy import create_engine, event from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session from sqlalchemy.orm import Query class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] status: Mapped[str] engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) def after_bulk_update_handler(update_context): print('updated rows:', update_context.rowcount) event.remove(Query, 'after_bulk_update', after_bulk_update_handler) event.listen(Query, 'after_bulk_update', after_bulk_update_handler) with Session(engine) as session: session.add_all([ Article(title='article 1', status='draft'), Article(title='article 2', status='draft'), ]) session.commit() session.query(Article).filter( Article.status == 'draft' ).update({'status': 'published'}) session.commit() session.query(Article).filter( Article.status == 'published' ).update({'status': 'archived'}) session.commit()

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

"updated rows: 2"

Второе обновление уже не вызвало обработчик, так как мы отписались от события через event.remove.

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

  • событие after_bulk_delete,
    которое срабатывает после массового удаления
  • функцию listen,
    которая подписывает обработчик на событие
  • функцию remove,
    которая отписывает обработчик от события
  • событие after_update,
    которое срабатывает после обновления отдельного объекта
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить