Как указать в модели для поля возможность значения как string так и null?
Пробовал как в документации, но это не работает https://field-idempotency--pydantic-docs.netlify.app/usage/types/ В итоговой схеме json, нет никаких инструкций насчёт того что поле может принимать значение null и string. Максимум чего я добился - игнорирование ошибки если поля нет в принципе. Вот что я пытался сделать:
none_or_str: str
none_or_str: str | None
none_or_str: Optional[str] = ...
none_or_str: str = Field(...)
Код для воспроизведения проблемы:
from typing import TypedDict, Optional
from pydantic import BaseModel, Field
import json
from jsonschema import validate
def validate_schema(instance: dict, schema: dict) -> None:
validate(instance=instance, schema=schema)
class TTest(BaseModel):
none_or_str: Optional[str] = None
j = '''{"none_or_str":null}'''
validate_schema(json.loads(j), TTest.schema())
Ошибка:
jsonschema.exceptions.ValidationError: None is not of type 'string'
Failed validating 'type' in schema['properties']['none_or_str']:
{'title': 'None Or Str', 'type': 'string'}
On instance['none_or_str']:
None
Ответы (2 шт):
Автор решения: aTrazanov
→ Ссылка
Сделал костыль. Без проверки на конкретное поле, как временное решение.
import json
import jsonschema
from jsonschema import validate
def validate_schema(instance: dict, schema: dict) -> None:
try:
validate(instance=instance, schema=schema)
except jsonschema.exceptions.ValidationError as e:
if "None is not of type 'string'" in str(e) and 'null_crunch' in str(e):
print('Validation pass, because have option null_crunch')
pass
else:
raise jsonschema.exceptions.ValidationError
class TTest(BaseModel):
none_or_str: Optional[str] = Field(..., null_crunch=True)
j = '''{"none_or_str":null}'''
validate_schema(json.loads(j), TTest.schema())
Автор решения: insolor
→ Ссылка
Похоже, что генерация схемы исправлена в будущей версии pydantic 2.*
(сейчас можно установить через pip install --pre -U "pydantic>=2.0a1"):
import json
from typing import Optional
from pydantic import BaseModel
from jsonschema import validate
class TTest(BaseModel):
none_or_str: Optional[str] = None
print(TTest.schema_json(indent=2))
# Вывод:
# {
# "title": "TTest",
# "type": "object",
# "properties": {
# "none_or_str": {
# "anyOf": [
# {
# "type": "string"
# },
# {
# "type": "null"
# }
# ],
# "default": null,
# "title": "None Or Str"
# }
# }
# }
def validate_schema(instance: dict, schema: dict) -> None:
validate(instance=instance, schema=schema)
j = '''{"none_or_str":null}'''
validate_schema(json.loads(j), TTest.schema()) # Без ошибок
j = '''{"none_or_str":123}'''
validate_schema(json.loads(j), TTest.schema()) # Ошибка валидации