Существует ли передовая практика определения необязательных полей в моделях Pydantic?

Я работаю с Pydantic для проверки данных в проекте Python и столкнулся с проблемой при указании необязательных полей в моем файле BaseModel.

from pydantic import BaseModel

class MyModel(BaseModel):
    author_id: int | None    # Case 1: throws error
    author_id: Optional[int] # Case 2: throws error
    author_id: int = None    # Case 3: works

Теперь, запрашивая конечную точку, которая принимает указанную выше модель в качестве тела JSON, я не предоставляю поле author_id в запросе.

Когда я использую author_id: int | None, я получаю сообщение об ошибке, сообщающее, что обязательное поле отсутствует. Однако, если я изменю его на author_id: Optional[int], я столкнусь с той же ошибкой. Но когда я использую author_id: int = None или author_id: Optional[int] = None, модель работает как положено, без ошибок. (Работает, если присутствует =)

Есть ли у вас какие-либо рекомендации о том, как правильно определять необязательные поля в моделях Pydantic? Существует ли конкретная версия Pydantic (или другой библиотеки), поддерживающая int | Нет синтаксиса правильно?

  • питон == 3.11
  • пидантик == 2.8.1
  • фастапи==0.111.1

Поле не является обязательным; вы пытаетесь выяснить, как инициализировать обязательный атрибут из JSON, в котором отсутствует ключ. У вас возникла бы та же проблема, если бы значением по умолчанию было другое целое число вместо None.

chepner 27.08.2024 21:50
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
1
51
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я думаю, что случай 1 является каноническим решением, но вы еще не определили необязательное поле (поскольку вы не указали значение по умолчанию). Вы хотите:

from pydantic import BaseModel


class MyModel(BaseModel):
    author_id: int | None = None

С этим определением:

>>> MyModel()
MyModel(author_id=None)
>>> MyModel(author_id=1)
MyModel(author_id=1)
Ответ принят как подходящий

Причина, по которой вы столкнулись с ошибкой, заключается в том, что не существует значения по умолчанию. Аннотации сами по себе ничего не делают.

Все приведенные ниже варианты работают и внутри практически эквивалентны. Третий вариант теперь рекомендуется для проектов, использующих только Python 3.10+.

from pydantic import BaseModel

class MyModel(BaseModel):
    author_id: Optional[int] = None # the original way
    author_id: Union[int, None] = None # another option
    author_id: int | None = None # more modern option (Python 3.10+)

Цитирование рекомендации третьего варианта по сравнению с остальными?

Woodford 27.08.2024 21:40

Он короче и доступен без дополнительного импорта из typing, но в остальном я не думаю, что он (настоятельно) рекомендуется по сравнению с двумя другими.

chepner 27.08.2024 21:49
docs.python.org/3.10/library/stdtypes.html#types-union по умолчанию используется новый синтаксис, PEP-604 описывает этот вариант как «упрощенный»
TemaSaur 27.08.2024 21:55

Я вижу, что стиль оператора объединения описан как эквивалент Optional, но не вижу рекомендаций в ту или иную сторону. Хороший ответ, но я бы заменил «рекомендуется» на «доступно».

Woodford 27.08.2024 22:47

Нашел! github.com/python/cpython/pull/30222

TemaSaur 27.08.2024 23:09

Другие вопросы по теме