pydantic文档:https://pydantic-docs.helpmanual.io/
Github https://github.com/samuelcolvin/pydantic/
安装
pip install pydantic
示例
# -*- coding: utf-8 -*-
from datetime import datetime, date
from pathlib import Path
from typing import List, Optional
from pydantic import BaseModel, ValidationError, constr
from sqlalchemy import Column, Integer, String
from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy.ext.declarative import declarative_base
def print_color(text):
"""PyCharm控制台打印带颜色的文字"""
print(f"\033[31m===== {text} =====\033[0m")
1、基本使用
class User(BaseModel):
id: int # 无默认值,必填字段
name = 'John Doe' # 有默认值,选填字段
signup_ts: Optional[datetime] = None # 选填字段
friends: List[int] = [] # 列表中的元素是int类型或者是可以转换成int类型的其他类型
external_data = {
'id': '123',
'signup_ts': '2017-06-01 12:22',
'friends': [1, '2', b'3']
}
user = User(**external_data)
print(user)
# > User id=123 name='John Doe' signup_ts=datetime.datetime(2017, 6, 1, 12, 22) friends=[1, 2, 3]
print(user.id)
# > 123
2、错误校验
error_data = {
'id': 'a123',
'signup_ts': '2017-06-01 12:22',
'friends': [1, '2', '3']
}
try:
User(**error_data)
except ValidationError as e:
print(e.json())
"""
[
{
"loc": [
"id"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
"""
3、模型类的属性和方法
# 实例方法
print(user.dict())
print(user.json())
print(user.copy()) # 浅拷贝
print(user.schema())
print(user.schema_json())
"""
{'id': 123, 'signup_ts': datetime.datetime(2017, 6, 1, 12, 22), 'friends': [1, 2, 3], 'name': 'John Doe'}
{"id": 123, "signup_ts": "2017-06-01T12:22:00", "friends": [1, 2, 3], "name": "John Doe"}
id=123 signup_ts=datetime.datetime(2017, 6, 1, 12, 22) friends=[1, 2, 3] name='John Doe'
{
'title': 'User',
'type': 'object',
'properties': {
'id': {
'title': 'Id',
'type': 'integer'
},
'signup_ts': {
'title': 'Signup Ts',
'type': 'string',
'format': 'date-time'
},
'friends': {
'title': 'Friends',
'default': [],
'type': 'array',
'items': {'type': 'integer'}
},
'name': {
'title': 'Name',
'default': 'John Doe',
'type': 'string'
}
},
'required': ['id']
}
{
"title": "User",
"type": "object",
"properties": {
"id": {"title": "Id", "type": "integer"},
"signup_ts": {"title": "Signup Ts", "type": "string", "format": "date-time"},
"friends": {"title": "Friends", "default": [], "type": "array", "items": {"type": "integer"}},
"name": {"title": "Name", "default": "John Doe", "type": "string"}},
"required": ["id"]
}
"""
# 类方法
print(User.parse_obj(external_data))
print(User.parse_raw('{"id": 123, "signup_ts": "2017-06-01T12:22:00", "friends": [1, 2, 3], "name": "John Doe"}'))
path = Path("obj.json")
path.write_text('{"id": 123, "signup_ts": "2017-06-01T12:22:00", "friends": [1, 2, 3], "name": "John Doe"}')
print(User.parse_file(path))
"""
id=123 signup_ts=datetime.datetime(2017, 6, 1, 12, 22) friends=[1, 2, 3] name='John Doe'
id=123 signup_ts=datetime.datetime(2017, 6, 1, 12, 22) friends=[1, 2, 3] name='John Doe'
id=123 signup_ts=datetime.datetime(2017, 6, 1, 12, 22) friends=[1, 2, 3] name='John Doe'
"""
# 不进行数据校验
print(User.construct(path))
"""
signup_ts=None friends=[] name='John Doe'
"""
# 字段
print(User.__fields__.keys())
"""
dict_keys(['id', 'signup_ts', 'friends', 'name'])
"""
4、递归模型
class Sound(BaseModel):
sound: str
class Dog(BaseModel):
name: str
birthday: date = None
sound: List[Sound]
dog = Dog(name="Tom", birthday=date.today(), sound=[{'sound': 'wangwang'}, {'sound': 'miaomiao'}])
print(dog.dict())
"""
{
'name': 'Tom',
'birthday': datetime.date(2021, 2, 14),
'sound': [{'sound': 'wangwang'}, {'sound': 'miaomiao'}]
}
"""
5、ORM模型
Base = declarative_base()
class CompanyOrm(Base):
__tablename__ = 'companies'
id = Column(Integer, primary_key=True, nullable=True)
public_key = Column(String(20), index=True, nullable=True, unique=True)
name = Column(String(63), unique=True)
domains = Column(ARRAY(String(255)))
class CompanyMode(BaseModel):
id: int
public_key: constr(max_length=20)
name: constr(max_length=63)
domains: List[constr(max_length=255)]
class Config:
orm_mode = True
company_orm = CompanyOrm(
id=123,
public_key='foo_key',
name='Testing',
domains=['baidu.com', 'sina.com']
)
print(CompanyMode.from_orm(company_orm))
"""
id=123 public_key='foo_key' name='Testing' domains=['baidu.com', 'sina.com']
"""