Pydantic使用
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使用的更多相关文章
- Python - pydantic 入门介绍与 Models 的简单使用
前言 为啥要学这个,因为 FastAPI 是基于它进行开发的,而且是个不错的框架,所以有必要深入学习 前置学习 Python 类型提示:https://www.cnblogs.com/poloyy/p ...
- pydantic 支持Dotenv 文件设置变量
1. 安装 pip install pydantic pip install pydantic[dotenv] 注意: 安装pip install pydantic[dotenv]时会提示no mat ...
- 全面理解Python中的类型提示(Type Hints)
众所周知,Python 是动态类型语言,运行时不需要指定变量类型.这一点是不会改变的,但是2015年9月创始人 Guido van Rossum 在 Python 3.5 引入了一个类型系统,允许开发 ...
- Go 语言入门教程:安装
关注公众号:雨哥写 python. 学习 Go 语言,比较下和 python 的用法,争取对 python 有更深的理解. 为什么学 Go 我主要使用 python 语言,其他语言用得不多,希望学一门 ...
- FastAPI 快速搭建一个REST API 服务
最近正好在看好的接口文档方便的工具, 突然看到这个, 试了一下确实挺方便 快速示例 from fastapi import FastAPI from pydantic import BaseModel ...
- 三分钟了解 Python3 的异步 Web 框架 FastAPI
快速编码,功能完善.从启动到部署,实例详解异步 py3 框架选择 FastAPI 的原因. FastAPI 介绍 FastAPI 与其它 Python-Web 框架的区别 在 FastAPI 之前,P ...
- 用它5分钟以后,我放弃用了四年的 Flask
有一个非常简单的需求:编写一个 HTTP接口,使用 POST 方式发送一个 JSON 字符串,接口里面读取发送上来的参数,对其中某个参数进行处理,并返回. 如果我们使用 Flask 来开发这个接口,那 ...
- FastApi学习(一)
前言 学习不止 正文 介绍 FastApi是PythonWeb框架的'新晋干员',虽然年轻但是很能打 目前已有 12k start GitHub 官网 为什么说他能打呢?它内部使用了 Python 的 ...
- [Python] Uvicorn+FastAPI快速搞定Restful API开发
目录 安装模块 运行代码 运行命令 快速文档 安装模块 # 一个现代的,快速(高性能)python web框架 pip install fastapi # 主要用于加载和提供应用程序的服务器. pip ...
随机推荐
- JavaScript获取html表单值验证后跳转网页中的关键点
关键代码: 1.表单部分 <form action="Depart.jsp" name="myform" method="post" ...
- 【STM32】晶振,主时钟,外设频率介绍
首先,我用的是STM32F407,下方所有图片都是出自这芯片的文档,如果型号和我不同,需要找到对应的芯片说明文档,也许会有出入 先看一张时钟图 这里会着重说明高速的部分,低速(不管内部还是外部)只给R ...
- java代码定时备份mysql数据库及注意事项——基于 springboot
源码地址: https://gitee.com/kevin9401/BackUpDataBase git 拉取: https://gitee.com/kevin9401/BackUpDataBase. ...
- 理解JMX之介绍和简单使用
JMX最常见的场景是监控Java程序的基本信息和运行情况,任何Java程序都可以开启JMX,然后使用JConsole或Visual VM进行预览.下图是使用Jconsle通过JMX查看Java程序的运 ...
- SSO(单点登录)示例
此文为转载文章,出处:https://www.cnblogs.com/jpfss/p/9273680.html SSO在我们的应用中非常常见,例如我们在OA系统登录了,我们就可以直接进入采购系统,不需 ...
- maven管理本地jar包
maven作为包管理工具,好处不必多说.但是有些情况,比如需要引入第三方包,如快递鸟,支付宝,微信等jar包(当然有可能直接提供maven依赖),如果直接下载到本地之后,怎么整合到自己的maven工程 ...
- spring基于注解的声明式事务控制
package com.hope.service.impl;import com.hope.dao.IAccountDao;import com.hope.domain.Account;import ...
- Python模块和函数
目录 一.基础 二.特殊函数 一.基础 #导入模块 import xxx #调用 xxx.dd() from xxx import xx as dd #导入某个函数,as给函数加别名,调用xx() ...
- Mysql报错合集
目录 一.链接报错 客户端连接mysql出错 链接客户端出错 交互登陆mysql出现warning警告Using a password 导入数据到数据库报错ERROR 1050 登陆数据库提示-bas ...
- 【模型推理】量化实现分享一:详解 min-max 对称量化算法实现
欢迎关注我的公众号 [极智视界],回复001获取Google编程规范 O_o >_< o_O O_o ~_~ o_O 大家好,我是极智视界,本文剖析一下 m ...