Метод expunge
Метод expunge класса Session исключает
переданный объект из сессии, переводя его в состояние
detached. После этого сессия перестает отслеживать
изменения объекта, а сам объект теряет связь с базой данных
через эту сессию. Первым параметром метод принимает
экземпляр модели, который нужно исключить из сессии.
Метод полезен, когда нужно отменить добавление нового объекта до коммита, или когда требуется отвязать объект от сессии, чтобы дальше работать с ним независимо. Если объект не находится в сессии, метод не делает ничего и не вызывает ошибок.
Синтаксис
Session.expunge(instance)
Пример
Давайте создадим сессию, добавим в нее новый объект
и посмотрим на его состояние до и после вызова
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))
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(title='article')
session.add(article)
print('in session:', article in session)
session.expunge(article)
print('in session:', article in session)
Результат выполнения кода:
"in session: True"
"in session: False"
Пример
Давайте сохраним объект в базу, закоммитим его, а затем исключим из сессии, чтобы убедиться, что данные остались в базе:
from sqlalchemy import create_engine, String, 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] = mapped_column(String(50))
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(title='article')
session.add(article)
session.commit()
session.expunge(article)
print('detached:', article in session)
res = session.scalars(select(Article)).all()
print('titles:', [a.title for a in res])
Результат выполнения кода:
"detached: False"
"titles: ['article']"
Пример
Давайте исключим объект из сессии, а затем изменим его поле и закоммитим. Так как объект больше не в сессии, изменения не попадут в базу:
from sqlalchemy import create_engine, String, 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] = mapped_column(String(50))
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(title='article')
session.add(article)
session.commit()
session.expunge(article)
article.title = 'changed'
session.commit()
res = session.scalars(select(Article)).all()
print('titles:', [a.title for a in res])
Результат выполнения кода:
"titles: ['article']"
Смотрите также
-
класс
Session,
который управляет жизненным циклом объектов -
метод
expunge_all,
который исключает из сессии все объекты сразу -
метод
expire,
который помечает атрибуты объекта как устаревшие -
метод
close,
который закрывает сессию и освобождает ресурсы