Pydantic是一个用于数据建模/解析的Python库,具有高效的错误处理和自定义验证机制。截至目前,Pydantic主要用于FastAPI框架中,用于解析请求和响应,因为Pydantic内置了对JSON编码和解码的支持。
这篇文章涵盖了以下主题。
- 了解
BaseModel类 Optional在Pydantic中- Pydantic中的验证
- 自定义验证
- 使用Pydantic可选的
email-validator模块进行电子邮件验证
BaseModel
对于Pydantic的数据建模,我们需要定义一个继承自BaseModel 类和字段的类。自定义验证逻辑位于同一个模型类中。 让我们通过JSON解析的简单例子来理解。考虑一个代表用户数据的JSON。
输入
data = {"id":20, "name":"John", "age":42, "dept":"IT"}
对于解析,首先,我们需要导入BaseModel ,并声明一个User ,该类继承于BaseModel 。
from pydantic import BaseModel
from pprint import print
data = {"id":20, "name":"John", "age":42, "dept":"IT"}
class User(BaseModel):
id: int
name: str
age: int
dept: str
接下来,需要从User 类中实例化出一个对象。
user = User(**data)
pprint(user)
输出
User(id=20, name='John', age=42, dept='IT')
Pydantic中的可选性
User 类中的属性可以被声明为Optional 类型。如果我们不确定任何JSON字段是否会出现,我们可以将该特定类型声明为Optional ,如果该字段缺失,默认情况下,如果属性没有被初始化为默认值,Optional ,则返回None 。在这个例子中,让我们完全删除dept 字段。
from pydantic import BaseModel
from typing import Optional
from pprint import pprint
data = {"id":20, "name":"John", "age":42}
class User(BaseModel):
id: int
name: str
age: int
dept: Optional[str]
user = User(**data)
pprint(user)
输出
dept 字段的值是None ,因为它在输入数据中是缺失的。
User(id=20, name='John', age=42, dept=None)
Pydantic中的验证
在Pydantic中,为了获得更精细的错误细节,开发人员需要使用try/except 块。错误的类型将是pydantic.error_wrappers.ValidationError 。
在我们的JSON数据中,将id 字段修改为字符串,并导入ValidationError 。
输入数据
data = {"id":"default", "name":"John", "age":42}
程序
from pydantic import BaseModel, ValidationError
from typing import Optional
from pprint import pprint
data = {"id":"default", "name":"John", "age":42}
class User(BaseModel):
id: int
name: str
age: int
dept: Optional[str]
try:
user = User(**data)
pprint(user)
except ValidationError as error:
pprint(error)
错误
ValidationError(model='User', errors=[{'loc': ('id',), 'msg': 'value is not a valid integer', 'type': 'type_error.integer'}])
错误可以用JSON表示,以提高可读性。
try:
user = User(**data)
pprint(user)
except ValidationError as error:
print(error.json())
这将返回JSON。
[ { "loc": [ "id" ],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
自定义验证
Pydantic拥有有用的装饰器,用于属性的自定义验证。开发人员需要导入Pydanticvalidator 装饰器,并编写我们的自定义验证逻辑;例如,如果name 字段的长度小于3个字符,则引发一个错误。
输入数据
data = {"id":10, "name":"ab", "age":42}
程序
from pydantic import BaseModel, ValidationError, validator
from typing import Optional
from pprint import pprint
data = {"id":10, "name":"ab", "age":42}
class User(BaseModel):
id: int
name: str
age: int
dept: Optional[str]
@validator('name')
def validate_name(cls, name):
print('Length of Name:', len(name))
if len (name) < 3:
raise ValueError('Name length must be > 3')
return name
try:
user = User(**data)
print(user)
except ValidationError as e:
print(e.json())
错误
[ { "loc": [ "name" ],
"msg": "Name length must be > 3",
"type": "value_error"
}
]
电子邮件验证
涵盖电子邮件验证的原因是,可以利用Pydantic定制的可选email-validator 库。你将需要从email_validator 模块中导入validate_email 。使用@validator 装饰器,我们所需要做的就是用数据调用validate_email 。
输入数据
data = {"id":20, "name":"Sameer", "age":42, "email":"sameer@abc.com"}
程序
from pydantic import BaseModel, ValidationError, validator, Required
from typing import Optional
from pprint import pprint
from email_validator import validate_email
class User(BaseModel):
id: int
name: str
age: int
dept: Optional[str]
email: str
@validator('name')
def validateName(cls, name):
print('Length of Name:', len(name))
if (len(name) < 3):
raise ValueError('Name length must be > 3')
return name
@validator('email')
def validateEmail(cls, email):
valid_email = validate_email(email)
return valid_email.email
try:
user = User(**data)
pprint(user)
except ValidationError as e:
print(e.json())
输出
User(id=20, name='Sameer', age=42, dept=None, email='sameer@abc.com')
让我们把email 的值改为错误的email-id 。
data = {"id":20, "name":"Sameer", "age":42, "email":"sameer"}
错误
[ { "loc": [ "email" ],
"msg": "The email address is not valid. It must have exactly one @-sign.",
"type": "value_error.emailsyntax"
}
]
这清楚地表明,@ 符号丢失。在提供了正确的email-id ,它按顺序返回了一切。
结论
Pydantic可以与任何基于Python的框架一起使用,它也支持本地JSON编码和解码。正如我们在整个文章中所看到的那样,采用Pydantic是很简单的,它有各种内置的类和装饰器,有助于有效地进行数据建模、验证和错误处理。
数据建模 IT JSON 类型 属性(计算) 数据(计算) Id(编程语言) LESS Python(语言) 数据类型
DZone贡献者所表达的观点是他们自己的。