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

Исключение ObjectDeletedError

Исключение ObjectDeletedError наследуется от класса StaleDataError и возникает, когда ORM пытается выполнить UPDATE или DELETE для строки, которой уже нет в базе данных. Это типичная ситуация при параллельной работе нескольких сессий с одними и теми же данными. Исключение не принимает дополнительных параметров при создании, но содержит информацию об объекте и его состоянии на момент ошибки.

Чаще всего исключение появляется при вызове метода flush или commit, когда SQLAlchemy пытается синхронизировать состояние объекта с базой данных, но обнаруживает, что строка уже удалена.

Синтаксис

from sqlalchemy.orm.exc import ObjectDeletedError

Пример

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

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]

Теперь выполним сценарий с удалением строки в обход ORM:

from sqlalchemy import create_engine, text from sqlalchemy.orm import Session from sqlalchemy.orm.exc import ObjectDeletedError from models import Base, Article engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: article = Article( title='article', text='some text', status='draft', num=1 ) session.add(article) session.commit() # delete row directly, bypassing ORM session.execute( text('DELETE FROM articles WHERE id = :id'), {'id': article.id} ) session.commit() try: article.title = 'updated article' session.commit() except ObjectDeletedError as e: print('ObjectDeletedError:', e)

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

"ObjectDeletedError: Instance '<Article at 0x...>' has been deleted, or its row is otherwise not present."

Пример

Давайте покажем, как перехватить исключение и корректно обработать ситуацию с удаленным объектом:

from sqlalchemy import create_engine, text from sqlalchemy.orm import Session from sqlalchemy.orm.exc import ObjectDeletedError from models import Base, Article engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: article = Article( title='article', text='some text', status='published', num=10 ) session.add(article) session.commit() # another session deletes the row with Session(engine) as other: other.execute( text('DELETE FROM articles WHERE id = :id'), {'id': article.id} ) other.commit() try: article.status = 'archived' session.commit() except ObjectDeletedError: print('Row was deleted by another session') print('Recovering object state') session.rollback()

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

"Row was deleted by another session" "Recovering object state"

Пример

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

from sqlalchemy import create_engine, text from sqlalchemy.orm import Session from sqlalchemy.orm.exc import ObjectDeletedError from models import Base, Article engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine) as session: article = Article( title='article', text='to be deleted', status='draft', num=5 ) session.add(article) session.commit() session.execute( text('DELETE FROM articles WHERE id = :id'), {'id': article.id} ) session.commit() try: session.delete(article) session.commit() except ObjectDeletedError as e: print('Caught:', type(e).__name__)

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

"Caught: ObjectDeletedError"

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

  • исключение StaleDataError,
    родительский класс для ObjectDeletedError
  • исключение SQLAlchemyError,
    базовый класс всех исключений SQLAlchemy
  • исключение FlushError,
    возникает при ошибках во время flush сессии
  • исключение DetachedInstanceError,
    возникает при обращении к отсоединенному объекту
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить