Метод get класса Session возвращает
экземпляр модели по значению первичного ключа.
Первым параметром метод принимает класс модели,
вторым - значение первичного ключа. Если объект
не найден, метод возвращает None. Метод
сначала ищет объект в identity map (карте
идентичности) сессии, и только потом обращается
к базе данных.
Синтаксис
Session.get(entity, ident, [options])
Пример
Давайте создадим модель и получим объект по
первичному ключу:
<+python+>
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',
text='some text',
status='draft',
num=1
)
session.add(article)
session.commit()
res = session.get(Article, article.id)
print(res)
print(res.title)
<-python+>
Результат выполнения кода:
<+python+>
"article"
<-python+>
Пример
Давайте попробуем получить объект по
несуществующему первичному ключу:
<+python+>
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:
res = session.get(Article, 999)
print(res)
<-python+>
Результат выполнения кода:
<+python+>
None
<-python+>
Пример
Давайте проверим, что метод get сначала
обращается к identity map сессии, не выполняя
запрос к базе данных для уже загруженного
объекта:
<+python+>
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:', echo=True)
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()
res1 = session.get(Article, article.id)
res2 = session.get(Article, article.id)
print(res1 is res2)
<-python+>
Итоговый SQL запрос:
<+sql+>
SELECT articles.id AS articles_id, articles.title AS articles_title, articles.text AS articles_text, articles.status AS articles_status, articles.num AS articles_num
FROM articles
WHERE articles.id = ?
<-sql+>
Результат выполнения кода:
<+python+>
True
<-python+>
Как видим, запрос к базе данных выполнился только
один раз, а второй вызов get вернул тот же
самый объект из identity map.
Смотрите также
-
класс
Session,
который управляет сессией работы с базой
-
метод
get_one,
который возвращает ровно один объект по ключу
-
метод
execute,
который выполняет запрос к базе данных
-
атрибут
identity_map,
который хранит загруженные объекты сессии