Метод one_or_none класса Query
Метод one_or_none класса Query выполняет запрос
и возвращает ровно одну запись. Если в результате запроса
нет ни одной строки, метод возвращает None. Если
в результате запроса оказалось больше одной строки, метод
вызывает исключение MultipleResultsFound. Метод не
принимает обязательных параметров и применяется к уже
построенному объекту запроса.
Синтаксис
query.one_or_none()
Пример
Пусть у нас есть модель Article, описывающая таблицу
articles. Создадим таблицу и добавим одну запись,
а затем найдем ее методом one_or_none:
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(100))
text: Mapped[str] = mapped_column(String(1000))
status: Mapped[str] = mapped_column(String(50))
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()
query = session.query(Article)
res = query.one_or_none()
print(res)
Результат выполнения кода:
"<Article(id=1, title='article', text='some text', status='draft', num=1)>"
Пример
Теперь рассмотрим случай, когда в таблице нет ни одной
записи. Метод one_or_none вернет None:
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(100))
text: Mapped[str] = mapped_column(String(1000))
status: Mapped[str] = mapped_column(String(50))
num: Mapped[int]
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
query = session.query(Article)
res = query.one_or_none()
print(res)
Результат выполнения кода:
"None"
Пример
Если в таблице больше одной подходящей записи, метод
one_or_none вызовет исключение
MultipleResultsFound. Рассмотрим такой случай:
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(100))
text: Mapped[str] = mapped_column(String(1000))
status: Mapped[str] = mapped_column(String(50))
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='draft', num=2),
])
session.commit()
query = session.query(Article)
res = query.one_or_none()
print(res)
Результат выполнения кода:
Traceback (most recent call last):
...
sqlalchemy.exc.MultipleResultsFound: Multiple rows were found when one or none was required
Пример
Метод one_or_none удобно комбинировать с методом
filter, чтобы получить гарантированно одну запись
или None:
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(100))
text: Mapped[str] = mapped_column(String(1000))
status: Mapped[str] = mapped_column(String(50))
num: Mapped[int]
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
session.add(Article(
title='article',
text='some text',
status='draft',
num=1
))
session.commit()
query = session.query(Article).filter(Article.title == 'article')
res = query.one_or_none()
print(res.title)
query = session.query(Article).filter(Article.title == 'user')
res = query.one_or_none()
print(res)
Результат выполнения кода:
"article"
"None"