Foutafhandeling
Pydantic zal een ValidationError
genereren wanneer het een fout vindt in de gegevens die het valideert.
!!! opmerking Validatiecode mag ValidationError
zelf niet verhogen, maar eerder een ValueError
of AssertionError
(of een subklasse daarvan) genereren die wordt opgevangen en gebruikt om ValidationError
in te vullen.
Er zal één uitzondering optreden, ongeacht het aantal gevonden fouten: ValidationError
zal informatie bevatten over alle fouten en hoe deze zijn gebeurd.
U kunt op verschillende manieren toegang krijgen tot deze fouten:
Methode | Beschrijving |
---|---|
e.errors() | Retourneert een lijst met fouten die zijn gevonden in de invoergegevens. |
e.error_count() | Retourneert het aantal gevonden fouten in errors . |
e.json() | Retourneert een JSON-weergave van errors . |
str(e) | Retourneert een voor mensen leesbare weergave van de fouten. |
Elk foutobject bevat:
Eigendom | Beschrijving |
---|---|
ctx | Een optioneel object dat waarden bevat die nodig zijn om het foutbericht weer te geven. |
input | De invoer die ter validatie is verstrekt. |
loc | De locatie van de fout als een lijst. |
msg | Een voor mensen leesbare uitleg van de fout. |
type | Een door de computer leesbare identificatie van het fouttype. |
url | De URL naar meer informatie over de fout. |
Het eerste item in de loc
zal het veld zijn waar de fout is opgetreden, en als het veld een submodel is, zullen volgende items aanwezig zijn om de geneste locatie van de fout aan te geven.
Als demonstratie:
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',
},
]
"""
Aangepaste fouten¶
In uw aangepaste gegevenstypen of validators moet u ValueError
of AssertionError
gebruiken om fouten te genereren.
Zie validators voor meer details over het gebruik van de @validator
decorateur.
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',
}
]
"""
U kunt ook PydanticCustomError
gebruiken om de foutstructuur volledig te controleren:
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]
"""
Foutmeldingen¶
Pydantic probeert nuttige standaardfoutmeldingen te bieden voor validatie- en gebruiksfouten.
We hebben documentatie voor standaardfoutcodes verstrekt in de volgende secties:
Pas foutmeldingen aan¶
U kunt foutmeldingen aanpassen door een aangepaste fouthandler te maken.
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',
},
]
"""
Een veelvoorkomend gebruiksscenario is het vertalen van foutmeldingen. In het bovenstaande voorbeeld kunnen we bijvoorbeeld de foutmeldingen vertalen door het woordenboek CUSTOM_MESSAGES
te vervangen door een woordenboek met vertalingen.
Een ander voorbeeld is het aanpassen van de manier waarop de 'loc'
waarde van een fout wordt weergegeven.
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',
}
]
"""
- Standaard produceert
e.errors()
een lijst met fouten metloc
-waarden die de vorm aannemen van tupels. - Met onze aangepaste
loc_to_dot_sep
-functie hebben we de vorm van deloc
representatie aangepast.
本文总阅读量次