Pydantic可以在代码运行时提供类型提示, 数据校验失败时提供友好的错误提示, 使用Python的类型注解来进行数据校验和settings管理

一般使用

from datetime import datetime
from typing import List
from typing import Optional from pydantic import BaseModel # 1 定义模型
class User(BaseModel):
id: int # 必须字段
name: str = "John Snow" # 有默认值,选填字段
signup_ts: Optional[datetime] = None
friends: List[int] = [] # 列表中元素是int类型或者可以直接转换成int类型 external_data = {
"id": "123",
"signup_ts": "2020-12-22 12:22",
"friends": [1, 2, "3"], # "3"是可以int("3")的
}
# 2 检验数据
user = User(**external_data)
# 3 访问数据
print(user.id, user.friends) # 实例化后调用属性
print(repr(user.signup_ts))
# .dict 方法, 返回数据字典
print(user.dict())

校验失败处理

假如数据检验不通过, 会抛出pydantic.ValidationError

from datetime import datetime

from typing import List
from typing import Optional from pydantic import BaseModel, ValidationError class User(BaseModel):
id: int # 必须字段
name: str = "John Snow" # 有默认值,选填字段
signup_ts: Optional[datetime] = None
friends: List[int] = [] # 列表中元素是int类型或者可以直接转换成int类型 external_data = {
"id": "123",
"signup_ts": "2020-12-22 12:22",
"friends": [1, 2, "3"], # "3"是可以int("3")的
} try:
User(id=1, signup_ts=datetime.today(), friends=[1, 2, "not number"])
except ValidationError as e:
print(e.json())
"""
[
{
"loc": [
"friends",
2
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
"""

模型类的的属性和方法

from datetime import datetime
from pathlib import Path
from typing import List
from typing import Optional from pydantic import BaseModel class User(BaseModel):
id: int # 必须字段
name: str = "John Snow" # 有默认值,选填字段
signup_ts: Optional[datetime] = None
friends: List[int] = [] # 列表中元素是int类型或者可以直接转换成int类型 external_data = {
"id": "123",
"signup_ts": "2020-12-22 12:22",
"friends": [1, 2, "3"], # "3"是可以int("3")的
}
user = User(**external_data) # 获得已检验数据的字典数据
print(user.dict()) # 获得已检验数据的json数据
print(user.json()) # 这里是浅拷贝
print(user.copy()) # 通过对象解析
print(User.parse_obj(external_data)) # 通过字符串解析
print(User.parse_raw('{"id": "123", "signup_ts": "2020-12-22 12:22", "friends": [1, 2, "3"]}')) path = Path('pydantic_tutorial.json')
path.write_text('{"id": "123", "signup_ts": "2020-12-22 12:22", "friends": [1, 2, "3"]}')
# 通过文本解析
print(User.parse_file(path)) # 获得对象 概要
# {'title': 'User', 'type': 'object', 'properties': {'id': ...} }
print(user.schema())
# 获得对象 概要json
# {'title': 'User', 'type': 'object', 'properties': {'id': ...} }
print(user.schema_json()) user_data = {"id": "error", "signup_ts": "2020-12-22 12 22", "friends": [1, 2, 3]} # id是字符串 是错误的
# 不检验数据直接创建模型类,不建议在construct方法中传入未经验证的数据
print(User.construct(**user_data)) # 获得所有字段
# 定义模型类的时候,所有字段都注明类型,字段顺序就不会乱
print(User.__fields__.keys())

模型嵌套

from datetime import datetime, date

from typing import List
from typing import Optional from pydantic import BaseModel class User(BaseModel):
id: int # 必须字段
name: str = "John Snow" # 有默认值,选填字段
signup_ts: Optional[datetime] = None
friends: List[int] = [] # 列表中元素是int类型或者可以直接转换成int类型 external_data = {
"id": "123",
"signup_ts": "2020-12-22 12:22",
"friends": [1, 2, "3"], # "3"是可以int("3")的
}
user = User(**external_data) class Sound(BaseModel):
sound: str class Dog(BaseModel):
birthday: date
weight: float = Optional[None]
sound: List[Sound] # 不同的狗有不同的叫声。递归模型(Recursive Models)就是指一个嵌套一个 dogs = Dog(birthday=date.today(), weight=6.66, sound=[{"sound": "wang wang ~"}, {"sound": "ying ying ~"}])
print(dogs.dict())

与ORM结合

from datetime import datetime

from typing import List
from typing import Optional from pydantic import BaseModel
from pydantic import constr
from sqlalchemy import Column, Integer, String
from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class CompanyOrm(Base):
__tablename__ = 'companies'
id = Column(Integer, primary_key=True, nullable=False)
public_key = Column(String(20), index=True, nullable=False, unique=True)
name = Column(String(63), unique=True)
domains = Column(ARRAY(String(255))) class CompanyModel(BaseModel):
id: int
# constr用于约束字符串
public_key: constr(max_length=20)
name: constr(max_length=63)
domains: List[constr(max_length=255)] class Config:
orm_mode = True co_orm = CompanyOrm(
id=123,
public_key='foobar',
name='Testing',
domains=['example.com', 'foobar.com'],
) print(CompanyModel.from_orm(co_orm))

验证器

如何使用及参数见passwords_match方法

from pydantic import BaseModel, ValidationError, validator

class UserModel(BaseModel):
name: str
username: str
password1: str
password2: str @validator('name')
def name_must_contain_space(cls, v, **kwargs):
if ' ' not in v:
raise ValueError('must contain a space')
return v.title() @validator('password2')
def passwords_match(cls, v, values, **kwargs):
"""
:param v: 当前字段的值: zxcvbn2
:param values: 已经验证的数据: {'username': 'scolvin', 'password1': 'zxcvbn'}
:param kwargs: {'field': ModelField(name='password2', type=str, required=True),
'config': <class '__main__.Config'>}
:return:
""" if 'password1' in values and v != values['password1']:
raise ValueError('passwords do not match')
return v @validator('username')
def username_alphanumeric(cls, v):
assert v.isalnum(), 'must be alphanumeric'
return v try:
UserModel(
name='samuel',
username='scolvin',
password1='zxcvbn',
password2='zxcvbn2',
)
except ValidationError as e:
print(e)
"""
2 validation errors for UserModel
name
must contain a space (type=value_error)
password2
passwords do not match (type=value_error)
"""

全部字段类型

见官方文档: Field Types

更多其他使用方法见: pydantic-docs

Pydantic使用的更多相关文章

  1. Python - pydantic 入门介绍与 Models 的简单使用

    前言 为啥要学这个,因为 FastAPI 是基于它进行开发的,而且是个不错的框架,所以有必要深入学习 前置学习 Python 类型提示:https://www.cnblogs.com/poloyy/p ...

  2. pydantic 支持Dotenv 文件设置变量

    1. 安装 pip install pydantic pip install pydantic[dotenv] 注意: 安装pip install pydantic[dotenv]时会提示no mat ...

  3. 全面理解Python中的类型提示(Type Hints)

    众所周知,Python 是动态类型语言,运行时不需要指定变量类型.这一点是不会改变的,但是2015年9月创始人 Guido van Rossum 在 Python 3.5 引入了一个类型系统,允许开发 ...

  4. Go 语言入门教程:安装

    关注公众号:雨哥写 python. 学习 Go 语言,比较下和 python 的用法,争取对 python 有更深的理解. 为什么学 Go 我主要使用 python 语言,其他语言用得不多,希望学一门 ...

  5. FastAPI 快速搭建一个REST API 服务

    最近正好在看好的接口文档方便的工具, 突然看到这个, 试了一下确实挺方便 快速示例 from fastapi import FastAPI from pydantic import BaseModel ...

  6. 三分钟了解 Python3 的异步 Web 框架 FastAPI

    快速编码,功能完善.从启动到部署,实例详解异步 py3 框架选择 FastAPI 的原因. FastAPI 介绍 FastAPI 与其它 Python-Web 框架的区别 在 FastAPI 之前,P ...

  7. 用它5分钟以后,我放弃用了四年的 Flask

    有一个非常简单的需求:编写一个 HTTP接口,使用 POST 方式发送一个 JSON 字符串,接口里面读取发送上来的参数,对其中某个参数进行处理,并返回. 如果我们使用 Flask 来开发这个接口,那 ...

  8. FastApi学习(一)

    前言 学习不止 正文 介绍 FastApi是PythonWeb框架的'新晋干员',虽然年轻但是很能打 目前已有 12k start GitHub 官网 为什么说他能打呢?它内部使用了 Python 的 ...

  9. [Python] Uvicorn+FastAPI快速搞定Restful API开发

    目录 安装模块 运行代码 运行命令 快速文档 安装模块 # 一个现代的,快速(高性能)python web框架 pip install fastapi # 主要用于加载和提供应用程序的服务器. pip ...

随机推荐

  1. 【Android】安装插件 + 改变文字大小、颜色 + 隐藏代码区块的直线

    安装插件 可以在搜寻框里面填入关键字搜寻,具体的插件,网上有很多介绍了 改变文字大小.颜色 隐藏代码区块的直线

  2. [项目总结]怎么获取TextView行数,为什么TextView获取行数为0?

    1 final TextView textView = new TextView(this); 2 ViewTreeObserver viewTreeObserver = textView.getVi ...

  3. 【Linux】【Services】【Project】Cobbler自动化装机

    1. 概念 1.1. Cobbler 1.2. PXE 1.3. 2. 版本信息 2.1. OS:Red Hat Enterprise Linux Server release 7.3 (Maipo) ...

  4. 通过spring-data-redis操作Redis

    一.操作String类型数据 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:spring/ ...

  5. 【Python】matplotlib直方图纵轴显示百分比

    其实很简单,就是算了一下百分比权重,乘以了一个权重值 import matplotlib.pyplot as plt from matplotlib.ticker import FuncFormatt ...

  6. Python的安装和卸载

    一.Python的安装,去Python官网https://www.python.org/downloads/下载对应安装包 进入官网后鼠标移动到downloads处然后点击Windows 二.安装包下 ...

  7. Win7远程连接问题:凭据不工作 & 没有授权此用户账户

    一 您的凭据不工作 1.问题描述 win7系统远程桌面到某个电脑的一个账户名为admin 的用户,但提示"您的凭据不工作,之前连到 *.*.*.*的凭据无法使用,请输入新凭据",即 ...

  8. Three.js 实现3D全景侦探小游戏🕵️

    背景 你是嘿嘿嘿侦探社实习侦探️,接到上级指派任务,到甄开心小镇调查市民甄不戳宝石失窃案,根据线人流浪汉老石‍提供的线索,小偷就躲在小镇,快把他找出来,帮甄不戳寻回失窃的宝石吧! 本文使用 Three ...

  9. Explain的详细使用

    官方文档 https://dev.mysql.com/doc/refman/5.7/en/explain-output.html explain俩种类型 explain extended 会在 exp ...

  10. WPF将窗口置于桌面下方(可用于动态桌面)

    WPF将窗口置于桌面下方(可用于动态桌面) 先来看一下效果: 界面元素很简单,就一个Button按钮,然后写个定时器,定时更新Button按钮中的内容为当前时间,下面来介绍下原理,和界面组成. 窗口介 ...