오류 처리
Pydantic은 검증 중인 데이터에서 오류를 발견할 때마다 ValidationError
를 발생시킵니다.
!!! note 유효성 검사 코드는 ValidationError
자체를 발생시켜서는 안 되며, ValidationError
채우는 데 사용되는 ValueError
또는 AssertionError
(또는 그 하위 클래스)를 발생시켜야 합니다.
발견된 오류 수에 관계없이 한 가지 예외가 발생합니다. ValidationError
모든 오류와 오류 발생 방식에 대한 정보가 포함됩니다.
여러 가지 방법으로 이러한 오류에 액세스할 수 있습니다.
방법 | 설명 |
---|---|
e.errors() | 입력 데이터에서 발견된 오류 목록을 반환합니다. |
e.error_count() | errors 에서 발견된 오류 수를 반환합니다. |
e.json() | errors 에 대한 JSON 표현을 반환합니다. |
str(e) | 사람이 읽을 수 있는 오류 표현을 반환합니다. |
각 오류 개체에는 다음이 포함됩니다.
재산 | 설명 |
---|---|
ctx | 오류 메시지를 렌더링하는 데 필요한 값이 포함된 선택적 개체입니다. |
input | 유효성 검사를 위해 제공된 입력입니다. |
loc | 오류 위치를 목록으로 표시합니다. |
msg | 사람이 읽을 수 있는 오류 설명입니다. |
type | 컴퓨터에서 읽을 수 있는 오류 유형 식별자입니다. |
url | 오류에 대한 추가 정보에 대한 URL입니다. |
loc
목록의 첫 번째 항목은 오류가 발생한 필드가 되며, 해당 필드가 하위 모델 인 경우 후속 항목이 나타나 오류의 중첩 위치를 나타냅니다.
데모로:
from typing import List
from pydantic import BaseModel, ValidationError, conint
class Location(BaseModel):
lat: float = 0.1
lng: float = 10.1
class Model(BaseModel):
is_required: float
gt_int: conint(gt=42)
list_of_ints: List[int] = None
a_float: float = None
recursive_model: Location = None
data = dict(
list_of_ints=['1', 2, 'bad'],
a_float='not a float',
recursive_model={'lat': 4.2, 'lng': 'New York'},
gt_int=21,
)
try:
Model(**data)
except ValidationError as e:
print(e)
"""
5 validation errors for Model
is_required
Field required [type=missing, input_value={'list_of_ints': ['1', 2,...ew York'}, 'gt_int': 21}, input_type=dict]
gt_int
Input should be greater than 42 [type=greater_than, input_value=21, input_type=int]
list_of_ints.2
Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='bad', input_type=str]
a_float
Input should be a valid number, unable to parse string as a number [type=float_parsing, input_value='not a float', input_type=str]
recursive_model.lng
Input should be a valid number, unable to parse string as a number [type=float_parsing, input_value='New York', input_type=str]
"""
try:
Model(**data)
except ValidationError as e:
print(e.errors())
"""
[
{
'type': 'missing',
'loc': ('is_required',),
'msg': 'Field required',
'input': {
'list_of_ints': ['1', 2, 'bad'],
'a_float': 'not a float',
'recursive_model': {'lat': 4.2, 'lng': 'New York'},
'gt_int': 21,
},
'url': 'https://errors.pydantic.dev/2/v/missing',
},
{
'type': 'greater_than',
'loc': ('gt_int',),
'msg': 'Input should be greater than 42',
'input': 21,
'ctx': {'gt': 42},
'url': 'https://errors.pydantic.dev/2/v/greater_than',
},
{
'type': 'int_parsing',
'loc': ('list_of_ints', 2),
'msg': 'Input should be a valid integer, unable to parse string as an integer',
'input': 'bad',
'url': 'https://errors.pydantic.dev/2/v/int_parsing',
},
{
'type': 'float_parsing',
'loc': ('a_float',),
'msg': 'Input should be a valid number, unable to parse string as a number',
'input': 'not a float',
'url': 'https://errors.pydantic.dev/2/v/float_parsing',
},
{
'type': 'float_parsing',
'loc': ('recursive_model', 'lng'),
'msg': 'Input should be a valid number, unable to parse string as a number',
'input': 'New York',
'url': 'https://errors.pydantic.dev/2/v/float_parsing',
},
]
"""
사용자 정의 오류¶
사용자 정의 데이터 유형 또는 유효성 검사기에서는 오류를 발생시키려면 ValueError
또는 AssertionError
사용해야 합니다.
@validator
데코레이터 사용에 대한 자세한 내용은 유효성 검사기를 참조하세요.
from pydantic import BaseModel, ValidationError, field_validator
class Model(BaseModel):
foo: str
@field_validator('foo')
def value_must_equal_bar(cls, v):
if v != 'bar':
raise ValueError('value must be "bar"')
return v
try:
Model(foo='ber')
except ValidationError as e:
print(e)
"""
1 validation error for Model
foo
Value error, value must be "bar" [type=value_error, input_value='ber', input_type=str]
"""
print(e.errors())
"""
[
{
'type': 'value_error',
'loc': ('foo',),
'msg': 'Value error, value must be "bar"',
'input': 'ber',
'ctx': {'error': ValueError('value must be "bar"')},
'url': 'https://errors.pydantic.dev/2/v/value_error',
}
]
"""
또한 PydanticCustomError
를 사용하여 오류 구조를 완전히 제어할 수도 있습니다:
from pydantic_core import PydanticCustomError
from pydantic import BaseModel, ValidationError, field_validator
class Model(BaseModel):
foo: str
@field_validator('foo')
def value_must_equal_bar(cls, v):
if v != 'bar':
raise PydanticCustomError(
'not_a_bar',
'value is not "bar", got "{wrong_value}"',
dict(wrong_value=v),
)
return v
try:
Model(foo='ber')
except ValidationError as e:
print(e)
"""
1 validation error for Model
foo
value is not "bar", got "ber" [type=not_a_bar, input_value='ber', input_type=str]
"""
오류 메시지¶
Pydantic은 유효성 검사 및 사용 오류에 대해 유용한 기본 오류 메시지를 제공하려고 시도합니다.
다음 섹션에서는 기본 오류 코드에 대한 설명서를 제공했습니다.
오류 메시지 사용자 정의¶
사용자 정의 오류 핸들러를 생성하여 오류 메시지를 사용자 정의할 수 있습니다.
from typing import Dict, List
from pydantic_core import ErrorDetails
from pydantic import BaseModel, HttpUrl, ValidationError
CUSTOM_MESSAGES = {
'int_parsing': 'This is not an integer! 🤦',
'url_scheme': 'Hey, use the right URL scheme! I wanted {expected_schemes}.',
}
def convert_errors(
e: ValidationError, custom_messages: Dict[str, str]
) -> List[ErrorDetails]:
new_errors: List[ErrorDetails] = []
for error in e.errors():
custom_message = custom_messages.get(error['type'])
if custom_message:
ctx = error.get('ctx')
error['msg'] = (
custom_message.format(**ctx) if ctx else custom_message
)
new_errors.append(error)
return new_errors
class Model(BaseModel):
a: int
b: HttpUrl
try:
Model(a='wrong', b='ftp://example.com')
except ValidationError as e:
errors = convert_errors(e, CUSTOM_MESSAGES)
print(errors)
"""
[
{
'type': 'int_parsing',
'loc': ('a',),
'msg': 'This is not an integer! 🤦',
'input': 'wrong',
'url': 'https://errors.pydantic.dev/2/v/int_parsing',
},
{
'type': 'url_scheme',
'loc': ('b',),
'msg': "Hey, use the right URL scheme! I wanted 'http' or 'https'.",
'input': 'ftp://example.com',
'ctx': {'expected_schemes': "'http' or 'https'"},
'url': 'https://errors.pydantic.dev/2/v/url_scheme',
},
]
"""
일반적인 사용 사례는 오류 메시지를 번역하는 것입니다. 예를 들어 위의 예에서는 CUSTOM_MESSAGES
사전을 번역 사전으로 대체하여 오류 메시지를 번역할 수 있습니다.
또 다른 예는 오류의 'loc'
값이 표시되는 방식을 사용자 정의하는 것입니다.
from typing import Any, Dict, List, Tuple, Union
from pydantic import BaseModel, ValidationError
def loc_to_dot_sep(loc: Tuple[Union[str, int], ...]) -> str:
path = ''
for i, x in enumerate(loc):
if isinstance(x, str):
if i > 0:
path += '.'
path += x
elif isinstance(x, int):
path += f'[{x}]'
else:
raise TypeError('Unexpected type')
return path
def convert_errors(e: ValidationError) -> List[Dict[str, Any]]:
new_errors: List[Dict[str, Any]] = e.errors()
for error in new_errors:
error['loc'] = loc_to_dot_sep(error['loc'])
return new_errors
class TestNestedModel(BaseModel):
key: str
value: str
class TestModel(BaseModel):
items: List[TestNestedModel]
data = {'items': [{'key': 'foo', 'value': 'bar'}, {'key': 'baz'}]}
try:
TestModel.model_validate(data)
except ValidationError as e:
print(e.errors()) # (1)!
"""
[
{
'type': 'missing',
'loc': ('items', 1, 'value'),
'msg': 'Field required',
'input': {'key': 'baz'},
'url': 'https://errors.pydantic.dev/2/v/missing',
}
]
"""
pretty_errors = convert_errors(e)
print(pretty_errors) # (2)!
"""
[
{
'type': 'missing',
'loc': 'items[1].value',
'msg': 'Field required',
'input': {'key': 'baz'},
'url': 'https://errors.pydantic.dev/2/v/missing',
}
]
"""
- 기본적으로
e.errors()
튜플 형식을 취하는loc
값을 사용하여 오류 목록을 생성합니다. - 사용자 정의
loc_to_dot_sep
함수를 사용하여loc
표현의 형식을 수정했습니다.
本文总阅读量次