Forwarded from Коробка с питоном
Зачем нужно делать кастомную базовую Pydantic модель?
Сейчас некоторые со мной не согласятся, но я часто рекомендую делать базовую
Наличие такой глобальной модели позволяет настраивать поведение всех моделей в приложении. Рассмотрю несколько кейсов, когда это может понадобится.
1) Контроль над входными данными.
Например, мы хотим округлять все поля которые называются
P.S.: В коментах подметили, что такой подход неявный, и я с этим согласен. Ничего не мешает для таких целей сделать ещё одну базовую модель (
2) Кастомый энкодер/декодер json.
Пакет
Это происходит из-за того, что операций по (дe)сериализации json в приложении может быть много, и смена библиотеки, в этом случае, дает ощутимый прирост к общей скорости.
В pydantic есть 2 опции в конфиге, которые позволяют изменять поведение энкодера и декодера. Выглядит это так:
Сейчас некоторые со мной не согласятся, но я часто рекомендую делать базовую
pydantic
модель и наследовать все модели от неё.Наличие такой глобальной модели позволяет настраивать поведение всех моделей в приложении. Рассмотрю несколько кейсов, когда это может понадобится.
1) Контроль над входными данными.
Например, мы хотим округлять все поля которые называются
price
до трех знаков после запятой. Сделать это можно так:class CustomBaseModel(BaseModel):Валидаторы дают возможность изменять входящие данные, но это стоит использовать с осторожностью.
@root_validator()
def round_price(cls, data: dict) -> dict:
prices = {k: round(v, 3) for k, v in data.items() if k == "price"}
return {**data, **prices}
P.S.: В коментах подметили, что такой подход неявный, и я с этим согласен. Ничего не мешает для таких целей сделать ещё одну базовую модель (
PriceRoundBaseModel
), наследуясь от нашей базовой СustomBaseModel
и использовать её там, где такое поведение необходимо.2) Кастомый энкодер/декодер json.
Пакет
json
из стандартной библиотеки очень медленный. При необходимости ускорить сервис этот пакет в первую очередь пытаются заменить на что-то побыстрее.Это происходит из-за того, что операций по (дe)сериализации json в приложении может быть много, и смена библиотеки, в этом случае, дает ощутимый прирост к общей скорости.
В pydantic есть 2 опции в конфиге, которые позволяют изменять поведение энкодера и декодера. Выглядит это так:
def orjson_dumps(v, *, default):#pydantic
# orjson.dumps возвращает байты, поэтому нам надо их декодить, чтобы соответствовать сигнатуре json.dumps
return orjson.dumps(v, default=default).decode()
class CustomBaseModel(BaseModel):
class Config:
json_loads = orjson.loads
json_dumps = orjson_dumps