Pydantic Ignore, Allow or Deny (with Error) Extra Input Fields Not Defined in Model Schema
If you are using Pydantic in Python, which is an excellent data parsing and validation library, you’ll often want to do one of the following three things with extra fields or attributes that are passed in the input data to build the models:
- Ignore the extra fields or attributes, i.e., they should not be present in the output model. This is the default behaviour.
- Allow the extra fields or attributes passed in the input data to be present in the output model.
- Deny the extra fields or attributes by throwing an exception.
Given the first one is the default, in some cases you may want to opt in for the second or third option. Let’s see how to do that with a Post
model example.
from pydantic import BaseModel, ValidationError
class Post(BaseModel):
id: int
title: str
body: str
try:
data = {
'id': 1,
'title': 'First Post',
'body': 'Post body',
'extra': 'Extra field', # Will be ignored
}
post = Post(**data)
print(post)
except ValidationError as e:
print(e)
In the code above, we create a simple Post
model with id
, title
and body
attributes or fields. We then create a model out of it with sample input data that contains a random extra
field.
By default the extra
field will be ignored (first option above) and this is what the post
model will look like:
print(post)
id=1 title='First Post' body='Post body'
Ok, so what if we want to allow passing of incoming extra fields in the input? We will have to specify that in the extra
option via Model Config like this:
from pydantic import BaseModel, ValidationError, Extra
class PostModel(BaseModel):
id: int
title: str
body: str
class Config:
extra = Extra.allow # or 'allow' str
We specify a Config
class inside the model with extra = Extra.allow
or extra = 'allow'
. This is what the new post
model will look like now:
print(post)
id=1 title='First Post' body='Post body' extra='Extra field'
The extra
field is now a part of post
.
Another common scenario is to completely deny any extra fields, i.e., raise an error (third option from the list above) for additional attributes. To achieve that, we will have to pass Extra.forbid
or 'forbid'
to the extra
config option.
from pydantic import ...
class PostModel(BaseModel):
...
class Config:
extra = Extra.forbid
try:
data = {
...
'extra': 'Extra field',
}
...
except ValidationError as e:
print(e)
Now when the code runs, it’ll raise a ValidationError
exception. This is what you’ll get from print(e)
:
1 validation error for PostModel
extra
extra fields not permitted (type=value_error.extra)
Bonus: There’s a shorter way to specify the extra
config option if that is the only option you’re configuring.
class PostModel(BaseModel, extra=Extra.forbid):
...
Although I still prefer the Config
inner class approach most of the time, since I configure multiple config options and specifying a list of them inside a class is much more cleaner/maintainable.