#python python... PYTHON 🔛 🚀
11 subscribers
914 photos
7 videos
158 files
1.54K links
Download Telegram
Зачем нужно делать кастомную базовую Pydantic модель?

Сейчас некоторые со мной не согласятся, но я часто рекомендую делать базовую 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):
# orjson.dumps возвращает байты, поэтому нам надо их декодить, чтобы соответствовать сигнатуре json.dumps
return orjson.dumps(v, default=default).decode()

class CustomBaseModel(BaseModel):
class Config:
json_loads = orjson.loads
json_dumps = orjson_dumps

#pydantic