Fehlerbehandlung
Pydantic löst einen ValidationError
aus, wenn es einen Fehler in den zu validierenden Daten findet.
!!! Hinweis Der Validierungscode sollte nicht ValidationError
selbst auslösen, sondern einen ValueError
oder AssertionError
(oder eine Unterklasse davon), der abgefangen und zum Auffüllen ValidationError
verwendet wird.
Unabhängig von der Anzahl der gefundenen Fehler wird eine Ausnahme ausgelöst. ValidationError
enthält Informationen zu allen Fehlern und deren Entstehung.
Sie können auf verschiedene Arten auf diese Fehler zugreifen:
Verfahren | Beschreibung |
---|---|
e.errors() | Gibt eine Liste der in den Eingabedaten gefundenen Fehler zurück. |
e.error_count() | Gibt die Anzahl der in errors gefundenen Fehler zurück. |
e.json() | Gibt eine JSON-Darstellung von errors zurück. |
str(e) | Gibt eine für Menschen lesbare Darstellung der Fehler zurück. |
Jedes Fehlerobjekt enthält:
Eigentum | Beschreibung |
---|---|
ctx | Ein optionales Objekt, das Werte enthält, die zum Rendern der Fehlermeldung erforderlich sind. |
input | Die zur Validierung bereitgestellte Eingabe. |
loc | Der Ort des Fehlers als Liste. |
msg | Eine für Menschen lesbare Erklärung des Fehlers. |
type | Eine computerlesbare Kennung des Fehlertyps. |
url | Die URL zu weiteren Informationen zum Fehler. |
Das erste Element in der loc
-Liste ist das Feld, in dem der Fehler aufgetreten ist. Wenn es sich bei dem Feld um ein Untermodell handelt, sind nachfolgende Elemente vorhanden, um die verschachtelte Position des Fehlers anzuzeigen.
Als Demonstration:
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',
},
]
"""
Benutzerdefinierte Fehler¶
In Ihren benutzerdefinierten Datentypen oder Validatoren sollten Sie ValueError
oder AssertionError
verwenden, um Fehler auszulösen.
Weitere Informationen zur Verwendung des @validator
Dekorators finden Sie unter Validatoren .
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',
}
]
"""
Sie können auch PydanticCustomError
verwenden, um die Fehlerstruktur vollständig zu steuern:
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]
"""
Fehlermeldungen¶
Pydantic versucht, nützliche Standardfehlermeldungen für Validierungs- und Verwendungsfehler bereitzustellen.
Wir haben in den folgenden Abschnitten Dokumentation für Standardfehlercodes bereitgestellt:
Passen Sie Fehlermeldungen an¶
Sie können Fehlermeldungen anpassen, indem Sie einen benutzerdefinierten Fehlerhandler erstellen.
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',
},
]
"""
Ein häufiger Anwendungsfall wäre die Übersetzung von Fehlermeldungen. Im obigen Beispiel könnten wir beispielsweise die Fehlermeldungen übersetzen und dabei das Wörterbuch CUSTOM_MESSAGES
durch ein Wörterbuch mit Übersetzungen ersetzen.
Ein weiteres Beispiel ist die Anpassung der Art und Weise, wie der 'loc'
-Wert eines Fehlers dargestellt wird.
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',
}
]
"""
- Standardmäßig erzeugt
e.errors()
eine Liste von Fehlern mitloc
-Werten, die die Form von Tupeln annehmen. - Mit unserer benutzerdefinierten Funktion
loc_to_dot_sep
haben wir die Form derloc
-Darstellung geändert.
本文总阅读量次