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

Исключение DetachedInstanceError

Исключение DetachedInstanceError наследуется от sqlalchemy.exc.SQLAlchemyError и возбуждается, когда выполняется доступ к атрибутам ORM-объекта, который уже не связан ни с одной активной сессией (Session). Такая ситуация называется отсоединенным (detached) состоянием. Обычно ошибка возникает при обращении к лениво загружаемым (lazy) атрибутам после закрытия сессии, коммита с expire_on_commit=True или после явного отсоединения объекта методом expunge. Параметров у самого исключения нет, но его текст содержит имя класса и атрибута, к которому произошло обращение.

Синтаксис

from sqlalchemy.exc import DetachedInstanceError raise DetachedInstanceError(message)

Пример

Давайте воспроизведем ошибку: закроем сессию и попробуем прочитать атрибут объекта после коммита с expire_on_commit=True:

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)) text: Mapped[str] = mapped_column(String(200)) engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine, expire_on_commit=True) as session: article = Article(title='article', text='sqlalchemy') session.add(article) session.commit() detached = article try: print(detached.title) except Exception as e: print(type(e).__name__) print(e)

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

"DetachedInstanceError" "Parent instance <Article at 0x...> is not bound to a Session; lazy load operation of attribute 'title' cannot proceed (Background on this error at: https://sqlalche.me/e/20/bhk3)"

Пример

Давайте исправим ситуацию и прочитаем атрибуты до закрытия сессии, либо используя expire_on_commit=False:

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)) text: Mapped[str] = mapped_column(String(200)) engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine, expire_on_commit=False) as session: article = Article(title='article', text='sqlalchemy') session.add(article) session.commit() detached = article print(detached.title) print(detached.text)

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

"article" "sqlalchemy"

Пример

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

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)) status: Mapped[str] = mapped_column(String(20)) engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine, expire_on_commit=False) as session: article = Article(title='article', status='draft') session.add(article) session.commit() session.expunge(article) try: print(article.title) except Exception as e: print(type(e).__name__)

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

"DetachedInstanceError"

Пример

Давайте присоединим отсоединенный объект обратно к сессии методом add и успешно прочитаем его атрибут:

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)) num: Mapped[int] = mapped_column() engine = create_engine('sqlite:///:memory:') Base.metadata.create_all(engine) with Session(engine, expire_on_commit=False) as session: article = Article(title='article', num=1) session.add(article) session.commit() session.expunge(article) with Session(engine, expire_on_commit=False) as new_session: new_session.add(article) print(article.title) print(article.num)

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

"article" 1

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

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