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

Метод with_for_update

Метод with_for_update класса Select добавляет к SQL-запросу конструкцию FOR UPDATE, которая блокирует выбранные строки до завершения транзакции. Это нужно, чтобы другие транзакции не могли изменить эти строки, пока текущая транзакция не завершится. Первым необязательным параметром метод принимает nowait, вторым - read, третьим - of, четвертым - skip_locked, пятым - key_share. Метод возвращает новый объект Select с добавленной блокировкой.

Синтаксис

Select.with_for_update(nowait=False, read=False, of=None, skip_locked=False, key_share=False)

Пример

Давайте создадим простой запрос с блокировкой строк таблицы articles и посмотрим итоговый SQL:

from sqlalchemy import select from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] text: Mapped[str] status: Mapped[str] num: Mapped[int] stmt = select(Article).with_for_update() print(stmt)

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

"SELECT articles.id, articles.title, articles.text, articles.status, articles.num FROM articles FOR UPDATE"

Пример

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

from sqlalchemy import select from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] text: Mapped[str] status: Mapped[str] num: Mapped[int] stmt = select(Article).where(Article.status == 'active').with_for_update(nowait=True) print(stmt)

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

SELECT articles.id, articles.title, articles.text, articles.status, articles.num FROM articles WHERE articles.status = 'active' FOR UPDATE NOWAIT

Пример

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

from sqlalchemy import select from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column class Base(DeclarativeBase): pass class Article(Base): __tablename__ = 'articles' id: Mapped[int] = mapped_column(primary_key=True) title: Mapped[str] text: Mapped[str] status: Mapped[str] num: Mapped[int] stmt = select(Article).with_for_update(skip_locked=True) print(stmt)

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

SELECT articles.id, articles.title, articles.text, articles.status, articles.num FROM articles FOR UPDATE SKIP LOCKED

Пример

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

from sqlalchemy import create_engine, select 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] text: Mapped[str] status: Mapped[str] num: Mapped[int] engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: session.add(Article(title='article 1', text='text 1', status='active', num=1)) session.add(Article(title='article 2', text='text 2', status='active', num=2)) session.commit() stmt = select(Article).where(Article.status == 'active').with_for_update() res = session.execute(stmt).scalars().all() for article in res: print(article.title)

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

"article 1" "article 2"

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

  • класс Select,
    который представляет SQL-запрос SELECT
  • метод where,
    который добавляет условие фильтрации к запросу
  • метод execution_options,
    который задает опции выполнения запроса
  • метод cte,
    который превращает запрос в общее табличное выражение
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить