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. linux 软链接与查看历史指令

    ln 说明 软连接也叫符号链接,类似于windows里的快捷方式,主要存放了路径. 基本语法 ln -s[原文件或目录][软连接名] 删除软链接 [root@hadoop102 ~]# rm -rf ...

  2. 学会这几步,简单集成视频编辑原子能力SDK

    华为视频编辑服务6.2.0版本上线后,我们为大家带来了两大变化:分别是丰富多样的AI能力和灵活选择的集成方式.为让开发者更快上手使用,今天小编带来了视频编辑原子能力SDK的具体集成方法.快来试试吧! ...

  3. A Child's History of England.8

    CHAPTER 3 ENGLAND UNDER THE GOOD SAXON, ALFRED Alfred [born in 849 CE, 唐: 618年-907年] the Great was a ...

  4. ps精修

    1.磨皮方法: a,, 添加高斯模糊后,按住alt键新建图层蒙版,设置前景色为白色,用画笔在脸上雀斑的位置涂抹,注意脸轮廓位置不要涂抹.最后添加曲线提亮 b. 添加蒙尘和划痕后,后面上面的一样

  5. 【Linux】【Commands】trouble shooting命令详解目录

    1. 简介 1.1. 最近看到阿里的运维招聘需要熟练掌握以下的命令,我就针对这几个命令做一下总结,有些命令我觉得别人总结的挺好了,我就不赘述了 1.2. 还有一些其他我觉得用得到的命令的用法会在第三部 ...

  6. mybatis中返回自动生成的id

    当有时我们插入一条数据时,由于id很可能是自动生成的,如果我们想要返回这条刚插入的id怎么办呢. 在mysql数据中我们可以在insert下添加一个selectKey用以指定返回的类型和值:     ...

  7. linux网络相关命令之脚本和centos启动流程

    nice 功用:设置优先权,可以改变程序执行的优先权等级.等级的范围从-19(最高优先级)到20(最低优先级).优先级为操作系统决定cpu分配的参数,优先级越高,所可能获得的 cpu时间越长. 语法: ...

  8. shell脚本实现网站日志分析统计

    如何用shell脚本分析与统计每天的访问日志,并发送到电子邮箱,以方便每天了解网站情况.今天脚本小编为大家介绍一款不错的shell脚本,可以实现如上功能. 本脚本统计了:1.总访问量2.总带宽3.独立 ...

  9. 3.3 GO字符串处理

    strings方法 index 判断子字符串或字符在父字符串中出现的位置(索引)Index 返回字符串 str 在字符串 s 中的索引( str 的第一个字符的索引),-1 表示字符串 s 不包含字符 ...

  10. 【Java基础】Java中如何获取一个类中泛型的实际类型

    泛型的术语 <>: 念做typeof List<E>: E称为类型参数变量 ArrayList<Integer>: Integer称为实际类型参数 ArrayLis ...