什么是Pydantic?

4,398 阅读4分钟

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贡献者所表达的观点是他们自己的。