Атрибут identity_map
Атрибут identity_map класса Session
возвращает отображение, в котором хранятся все объекты,
загруженные в текущей сессии. Ключом словаря выступает
кортеж вида (класс, идентификатор), а значением -
сам объект модели. Этот атрибут позволяет проверить,
какие объекты уже отслеживаются сессией, не выполняя
дополнительных запросов к базе данных. Параметров
атрибут не принимает, так как является свойством объекта
Session.
Синтаксис
session.identity_map
Пример
Давайте создадим модель, добавим объект в сессию
и посмотрим содержимое identity_map после сброса
изменений во время фиксации:
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.identity_map)
Результат выполнения кода:
"IdentitySet(<Article at 0x...>)"
Пример
Давайте проверим, содержит ли identity_map
конкретный объект по его классу и идентификатору:
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()
key = (Article, article.id)
print(key in session.identity_map)
print(session.identity_map[key] is article)
Результат выполнения кода:
True
True
Пример
Давайте посмотрим, как меняется размер
identity_map при загрузке объектов из базы данных:
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))
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:
session.add_all([
Article(title='article 1', text='text 1', status='draft', num=1),
Article(title='article 2', text='text 2', status='published', num=2)
])
session.commit()
print(len(session.identity_map))
res = session.scalars(select(Article)).all()
print(len(session.identity_map))
Результат выполнения кода:
2
2