Функция validates
Функция validates создает валидатор для одного или нескольких
атрибутов декларативной модели. Первым параметром передаются имена
атрибутов (строка или кортеж строк), для которых будет вызываться
метод-валидатор. Декоратор применяется к методу класса, который
принимает имя атрибута, устанавливаемое значение и необязательный
параметр oldvalue. Если валидатор возбуждает исключение
ValueError, AssertionError или Exception,
то изменение атрибута отменяется, а исключение пробрасывается
наружу.
Синтаксис
from sqlalchemy.orm import validates
@validates(*names, include_removes=False, include_backrefs=True)
def validate_method(self, key, value):
...
return value
Пример
Давайте создадим модель Article и добавим валидатор,
который проверяет, что заголовок не пустой:
from sqlalchemy import create_engine
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, validates, Session
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
@validates('title')
def validate_title(self, key, value):
if not value:
raise ValueError('title must not be empty')
return value
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(title='article')
session.add(article)
session.commit()
print(article.title)
Результат выполнения кода:
"article"
Пример
Давайте попробуем установить пустой заголовок и посмотрим, как сработает валидатор:
Результат выполнения кода:
"Error: title must not be empty"
"article"
Пример
Давайте создадим валидатор сразу для нескольких атрибутов
title и status, проверяющий длину значения:
from sqlalchemy import create_engine
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, validates, Session
class Base(DeclarativeBase):
pass
class Article(Base):
__tablename__ = 'articles'
id: Mapped[int] = mapped_column(primary_key=True)
title: Mapped[str]
status: Mapped[str]
@validates('title', 'status')
def validate_strings(self, key, value):
if len(value) > 100:
raise ValueError(f'{key} is too long')
return value
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
with Session(engine) as session:
article = Article(title='article', status='published')
session.add(article)
session.commit()
print(article.title, article.status)
Результат выполнения кода:
"article published"
Пример
Давайте с помощью параметра include_removes сделаем так,
чтобы валидатор вызывался и при удалении значения атрибута.
В этом случае третий аргумент метода будет равен True:
Результат выполнения кода:
"Setting title to article"
"Removing title"
Смотрите также
-
класс
DeclarativeBase,
который является базовым классом для декларативных моделей -
функцию
mapped_column,
которая описывает колонку таблицы в модели -
класс
Mapped,
который задаёт тип аннотированного атрибута модели -
функцию
reconstructor,
которая восстанавливает объект модели после десериализации