Метод one_or_none класса Session
Метод one_or_none класса Session
выполняет SQL-запрос и возвращает ровно одну строку
результата. Если запрос не вернул ни одной строки,
метод возвращает None. Если же запрос вернул
больше одной строки, метод выбрасывает исключение
MultipleResultsFound. Первым параметром метод
принимает SQL-выражение или ORM-запрос, который
нужно выполнить.
Синтаксис
Session.one_or_none(statement, [params])
Пример
Давайте создадим сессию, добавим одну статью
и получим ее методом one_or_none:
from sqlalchemy import create_engine, 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]
text: Mapped[str]
status: Mapped[str]
num: Mapped[int]
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(
title='article',
text='text',
status='published',
num=1
)
session.add(article)
session.commit()
stmt = select(Article).where(Article.title == 'article')
res = session.one_or_none(stmt)
print(res)
Результат выполнения кода:
<Article(id=1, title='article', text='text', status='published', num=1)>
Пример
Если запрос не находит ни одной строки,
метод one_or_none возвращает None.
Давайте это проверим:
from sqlalchemy import create_engine, 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]
text: Mapped[str]
status: Mapped[str]
num: Mapped[int]
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
stmt = select(Article).where(Article.title == 'user')
res = session.one_or_none(stmt)
print(res)
Результат выполнения кода:
None
Пример
Если запрос возвращает больше одной строки,
метод one_or_none выбрасывает исключение
MultipleResultsFound. Давайте добавим две
статьи и попробуем получить их этим методом:
from sqlalchemy import create_engine, 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]
text: Mapped[str]
status: Mapped[str]
num: Mapped[int]
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add_all([
Article(title='article', text='text 1', status='published', num=1),
Article(title='article', text='text 2', status='draft', num=2)
])
session.commit()
stmt = select(Article).where(Article.title == 'article')
try:
res = session.one_or_none(stmt)
print(res)
except Exception as e:
print(type(e).__name__)
Результат выполнения кода:
"MultipleResultsFound"
Пример
Метод one_or_none можно использовать
вместе с методом scalars, чтобы получить
не объект модели, а одно скалярное значение.
Давайте получим заголовок статьи:
from sqlalchemy import create_engine, 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]
text: Mapped[str]
status: Mapped[str]
num: Mapped[int]
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(
title='article',
text='text',
status='published',
num=1
)
session.add(article)
session.commit()
stmt = select(Article.title).where(Article.num == 1)
res = session.scalars(stmt).one_or_none()
print(res)
Результат выполнения кода:
"article"
Смотрите также
-
метод
one,
который возвращает ровно одну строку и падает при ее отсутствии -
метод
scalar_one_or_none,
который возвращает одно скалярное значение или None -
метод
scalars,
который возвращает скалярные значения из результата -
метод
first,
который возвращает первую строку результата или None