Метод is_modified
Метод is_modified класса Session проверяет, есть ли у переданного объекта несохраненные изменения в текущей сессии. Первым параметром метод принимает экземпляр модели, а вторым - необязательный флаг include_collections, который указывает, нужно ли учитывать изменения в коллекциях (связанных списках объектов). Метод возвращает логическое значение: True, если объект был изменен, и False в противном случае.
Синтаксис
session.is_modified(instance, [include_collections])
Пример
Давайте создадим модель, добавим объект в сессию и проверим его состояние до и после изменения атрибута:
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))
status: Mapped[str] = mapped_column(String(20))
num: Mapped[int]
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(
title='article 1',
text='some text',
status='draft',
num=1
)
session.add(article)
session.flush()
print(session.is_modified(article))
article.title = 'article 2'
print(session.is_modified(article))
Результат выполнения кода:
False
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))
status: Mapped[str] = mapped_column(String(20))
num: Mapped[int]
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(
title='article 1',
text='some text',
status='draft',
num=1
)
session.add(article)
session.commit()
article.status = 'published'
print(session.is_modified(article))
session.commit()
print(session.is_modified(article))
Результат выполнения кода:
True
False
Пример
Давайте посмотрим, как параметр include_collections влияет на результат при работе со связанными объектами:
from sqlalchemy import create_engine, String, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session, relationship
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))
status: Mapped[str] = mapped_column(String(20))
num: Mapped[int]
class Comment(Base):
__tablename__ = 'comments'
id: Mapped[int] = mapped_column(primary_key=True)
article_id: Mapped[int] = mapped_column(ForeignKey('articles.id'))
text: Mapped[str] = mapped_column(String(200))
article: Mapped[Article] = relationship()
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(
title='article 1',
text='some text',
status='draft',
num=1
)
session.add(article)
session.commit()
comment = Comment(article_id=article.id, text='comment 1')
session.add(comment)
session.commit()
article.comments = [comment]
print(session.is_modified(article, include_collections=False))
print(session.is_modified(article, include_collections=True))
Результат выполнения кода:
False
True