Функция func.nullif
Функция func.nullif создает SQL-выражение
NULLIF. Она принимает два аргумента:
первое выражение и второе выражение для сравнения.
Если первое выражение равно второму, функция
возвращает NULL, иначе возвращает первое
выражение. Это удобно для замены нежелательных
значений на NULL, например пустых строк или нулей.
Синтаксис
func.nullif(expression, value)
Пример
Давайте сравним два одинаковых значения и посмотрим на результат функции:
from sqlalchemy import func, select
stmt = select(func.nullif(1, 1))
print(stmt)
Итоговый SQL запрос:
SELECT nullif(:nullif_1, :nullif_2) AS nullif_1
Пример
Давайте сравним два разных значения. Так как они не равны, функция вернет первое выражение:
from sqlalchemy import func, select
stmt = select(func.nullif(1, 2))
print(stmt)
Итоговый SQL запрос:
SELECT nullif(:nullif_1, :nullif_2) AS nullif_1
Пример
Давайте применим функцию func.nullif к колонке
таблицы. Пусть нужно заменить статус 'deleted'
на NULL:
from sqlalchemy import String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
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(500))
status: Mapped[str] = mapped_column(String(50))
num: Mapped[int]
Теперь выполним запрос с функцией func.nullif
по колонке status:
from sqlalchemy import create_engine, func, select
from models import Article
engine = create_engine('sqlite:///:memory:')
with engine.connect() as conn:
stmt = select(
Article.title,
func.nullif(Article.status, 'deleted').label('status')
)
print(stmt)
Итоговый SQL запрос:
SELECT articles.title, nullif(articles.status, :nullif_1) AS status
FROM articles
Пример
Давайте посмотрим, как функция ведет себя при выполнении запроса с реальными данными:
from sqlalchemy import String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
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(500))
status: Mapped[str] = mapped_column(String(50))
num: Mapped[int]
Создадим таблицу, добавим записи и выполним запрос:
from sqlalchemy import create_engine, func, select
from models import Base, Article
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with engine.begin() as conn:
conn.execute(
Article.__table__.insert(),
[
{'title': 'article 1', 'text': 'text 1', 'status': 'deleted', 'num': 1},
{'title': 'article 2', 'text': 'text 2', 'status': 'active', 'num': 2},
]
)
with engine.connect() as conn:
stmt = select(
Article.title,
func.nullif(Article.status, 'deleted').label('status')
)
res = conn.execute(stmt).all()
print(res)
Результат выполнения кода:
[('article 1', None), ('article 2', 'active')]
Как видно из результата, для первой записи статус
'deleted' был заменен на None (то есть NULL),
а для второй записи статус остался прежним.
Смотрите также
-
функцию
func.coalesce,
которая заменяет NULL на заданное значение -
функцию
func,
которая создает произвольные SQL-функции -
выражение
null,
которое представляет SQL-значение NULL -
функцию
case,
которая создает условное SQL-выражение