pydantic模型
作者:互联网
模型
- 在
pydantic
中定义对象的主要方法是通过模型BaseModel
。
1.1基本模型
from pydantic import BaseModel
class User(BaseModel):
id: int # 整形、必须
name = 'Jane Doe' # 通过默认值推断类型为字符串,不是必须,因为提供有默认值
class Config:
max_anystr_length = 10
error_msg_templates = {
'value_error.any_str.max_length': 'max_length:{limit_value}',
}
user = User(id='123')
user.dict()
:返回字典user.json()
:返回json串user.copy()
:返回一个浅拷贝对象User.parse_obj()
:使用字典初始化对象User.parse_raw()
:使用json串初始化对象User.parse_file()
:使用文件初始化对象User.from_orm()
:从orm实例初始化对象user.schema()
:返回一个字典,将模型表示为 JSON 架构user.schema_json()
:返回 的 JSON 字符串表示形式User.construct()
:用于在不运行验证的情况下创建模型的类方法user.__fields_set__
:初始化模型实例时设置的字段名称集合user.__fields__
:模型字段的字典__config__
:模型的配置类
1.2递归模型
from typing import List
from pydantic import BaseModel
class Foo(BaseModel):
count: int
size: float = None
class Bar(BaseModel):
apple = 'x'
banana = 'y'
class Spam(BaseModel):
foo: Foo
bars: List[Bar]
m = Spam(foo={'count': 4}, bars=[{'apple': 'x1'}, {'apple': 'x2'}])
1.3ORM模型
- Pydantic模型可以从任意类实例创建,以支持映射到ORM对象的模型。
- "Config"属性必须设置为 。
orm_mode=True
- 必须使用特殊构造函数来创建模型实例。
from_orm
from typing import List
from pydantic import BaseModel, constr
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class BookOrm(Base):
__tablename__ = 'companies'
id = Column(Integer, primary_key=True, nullable=False)
name= Column(String(20), index=True, nullable=False, unique=True)
desc = Column(String(255), nullable=True, default='')
class BookModel(BaseModel):
id: int
name: constr(max_length=20)
desc: constr(max_length=255)
class Config:
orm_mode = True
book_orm = BookOrm(
id=1,
name='格林童话',
desc='《格林童话》是由德国语言学家雅各布·格林和威廉·格林兄弟收集、整理、加工完成的德国民间文学。《格林童话》里面约有200多个故事,大部分源自民间的口头传说,其中的《灰姑娘》《白雪公主》《小红帽》《青蛙王子》等童话故事较为闻名',
)
book_model = BookModel.from_orm(book_orm)
- 递归ORM模型
from typing import List from pydantic import BaseModel class BookCls: def __init__(self, *, name: str, desc: str): self.name = name self.desc = desc class AuthorCls: def __init__(self, *, name: str, age: float = None, books: List[BookCls]): self.name = name self.age = age self.books = books class Book(BaseModel): name: str desc: str class Config: orm_mode = True class Author(BaseModel): name: str age: float = None books: List[Book] class Config: orm_mode = True book1 = BookCls(name='平凡的世界', desc='《平凡的世界》以中国70年代中期到80年代中期十年间为背景,通过复杂的矛盾纠葛,以孙少安和孙少平两兄弟为中心,刻画了当时社会各阶层众多普通人的形象;劳动与爱情、挫折与追求、痛苦与欢乐、日常生活与巨大社会冲突纷繁地交织在一起,深刻地展示了普通人在大时代历史进程中所走过的艰难曲折的道路') book2 = BookCls(name='人生', desc='《人生》以改革时期陕北高原的城乡生活为时空背景,描写了高中毕业生高加林回到土地又离开土地,再回到土地这样人生的变化过程,构成了其故事构架。高加林同农村姑娘刘巧珍,城市姑娘黄亚萍之间的感情纠葛构成了故事发展的矛盾,也正是体现那种艰难选择的悲剧') moyan = AuthorCls(name='莫言', age=43, books=[book1, book2]) moyan_model = Author.from_orm(moyan) print(moyan_model) # name='莫言' age=20.0 books=[Book(name='平凡的世界', desc='《平凡的世界》以中国70年代中期到80年代中期十年间为背景,通过复杂的矛盾纠葛,以孙少安和孙少平两兄弟为中心,刻画了当时社会各阶层众多普通人的形象;劳动与爱情、挫折与追求、痛苦与欢乐、日常生活与巨大社会冲突纷繁地交织在一起,深刻地展示了普通人在大时代历史进程中所走过的艰难曲折的道路'), Book(name='人生', desc='《人生》以改革时期陕北高原的城乡生活为时空背景,描写了高中毕业生高加林回到土地又离开土地,再回到土地这样人生的变化过程,构成了其故事构架。高加林同农村姑娘刘巧珍,城市姑娘黄亚萍之间的感情纠葛构成了故事发展的矛盾,也正是体现那种艰难选择的悲剧')]
1.4通用模型
- Pydantic 支持创建通用模型,以便更轻松地重用通用模型结构。
from typing import Generic, TypeVar, Optional, List
from pydantic import BaseModel, validator, ValidationError
from pydantic.generics import GenericModel
# 定义泛型
DataT = TypeVar('DataT')
class Error(BaseModel):
code: int
message: str
class DataModel(BaseModel):
numbers: List[int]
people: List[str]
class Response(GenericModel, Generic[DataT]):
data: Optional[DataT] # data参数可以是任意类型
error: Optional[Error]
data = DataModel(numbers=[1, 2, 3], people=[])
error = Error(code=404, message='Not found')
print(Response[int](data=1).dict())
print(Response[str](data='value').dict())
print(Response(data=data, error=error).dict())
1.5模型字段不允许修改
from pydantic import BaseModel
class FooBarModel(BaseModel):
a: str
b: dict
class Config:
allow_mutation = False
# 一旦数据被初始化就不允许修改 allow_mutation = False
foobar = FooBarModel(a='hello', b={'apple': 'pear'})
try:
foobar.a = 'different'
except TypeError as e:
print(e)
1.6模型字段顺序
- 从 v1.0 开始,所有指定类型的字段(无论是仅指类型还是默认值)都将位于所有没有指定类型的字段之前
from pydantic import BaseModel, ValidationError
class Model(BaseModel):
a: int
b = 2
c: int = 1
d = 0
e: float
print(Model.__fields__.keys())
# dict_keys(['a', 'c', 'e', 'b', 'd']) # 报错也是保持这个字段顺序
1.7必填字段
from pydantic import BaseModel, Field
class Model(BaseModel):
a: int
b: int = ...
c: int = Field(...)
1.8必填可选字段
from typing import Optional
from pydantic import BaseModel, Field
class Model(BaseModel):
a: Optional[int] # 可选,默认值None
b: Optional[int] = ...
c: Optional[int] = Field(...)
1.9动态默认值
from uuid import UUID, uuid4
from pydantic import BaseModel, Field
class Model(BaseModel):
uid: UUID = Field(default_factory=uuid4)
updated: datetime = Field(default_factory=datetime.utcnow)
2.0自动排除属性
- 以下划线开头的类变量和带ClassVar注释的属性将自动从模型中排除
from pydantic import BaseModel
from typing import ClassVar
class Model(BaseModel):
id: int = 1
_name: str = "jack"
age: ClassVar = 23
print(Model.__fields__.keys()) # dict_keys(['id'])
m1 = Model()
print(m1._name) # jack
print(m1.age) # 23
2.1私有属性
- 私有属性名称必须以下划线开头,以防止与模型字段冲突
- _attr、__attr__两者都支持
from datetime import datetime
from pydantic import BaseModel, Field, PrivateAttr
class Model(BaseModel):
updated: datetime = Field(default_factory=datetime.utcnow)
# 私有属性需要更改或操作模型实例上的内部属性使用PrivateAttr而不是Field
_updated: datetime = Field(default_factory=datetime.utcnow)
_updated1: datetime = PrivateAttr(default_factory=datetime.utcnow)
__updated2__: datetime = PrivateAttr(default_factory=datetime.utcnow)
print(m1.__private_attributes__)
# {'_updated1': ModelPrivateAttr(default=PydanticUndefined, default_factory=<built-in method utcnow of type object at 0x00007FFD07BAF720>), '__updated2__': ModelPrivateAttr(default=PydanticUndefined, default_factory=<built-in method utcnow of type object at 0x00007FFD07BAF720>)}
m1 = Model()
print(m1.updated) # 2022-06-15 03:12:05.524165
print(m1._updated) # default=PydanticUndefined default_factory=<built-in method utcnow of type object at 0x00007FFD07BAF720> extra={}
print(m1._updated1) # 2022-06-15 03:12:05.524165
Config.underscore_attrs_are_private=True
,则任何非 ClassVar 下划线属性都将被视为私有
class Model(BaseModel):
updated: datetime = Field(default_factory=datetime.utcnow)
# 私有属性需要更改或操作模型实例上的内部属性使用PrivateAttr而不是Field
_updated: datetime = Field(default_factory=datetime.utcnow)
_updated1: datetime = PrivateAttr(default_factory=datetime.utcnow)
__updated2__: datetime = PrivateAttr(default_factory=datetime.utcnow)
class Config:
# 此时_updated也成为了私有属性
underscore_attrs_are_private = True
print(m1.__private_attributes__)
# {'_updated': ModelPrivateAttr(default=FieldInfo(default=PydanticUndefined, default_factory=<built-in method utcnow of type object at 0x00007FFD07BAF720>, extra={})), '_updated1': ModelPrivateAttr(default=PydanticUndefined, default_factory=<built-in method utcnow of type object at 0x00007FFD07BAF720>), '__updated2__': ModelPrivateAttr(default=PydanticUndefined, default_factory=<built-in method utcnow of type object at 0x00007FFD07BAF720>)}
2.2将数据解析为指定类型
parse_obj_as
from typing import List
from pydantic import BaseModel, parse_obj_as
class Item(BaseModel):
id: int
name: str
# `item_data` could come from an API call, eg., via something like:
# item_data = requests.get('https://my-api.com/items').json()
item_data = [{'id': 1, 'name': 'My Item'}]
items = parse_obj_as(List[Item], item_data)
print(items)
# [Item(id=1, name='My Item')]
2.3数据转换
from pydantic import BaseModel
class Model(BaseModel):
a: int
b: float
c: str
print(Model(a=3.1415, b=' 2.72 ', c=123).dict())
# {'a': 3, 'b': 2.72, 'c': '123'}
2.4严格模式
from pydantic import BaseModel, conint, confloat, constr, ValidationError
class Model(BaseModel):
a: conint(strict=True)
b: confloat(strict=True)
c: constr(strict=True)
try:
print(Model(a=3.1415, b=' 2.72 ', c=123).dict())
except ValidationError as e:
print(str(e))
'''
3 validation errors for Model
a
value is not a valid integer (type=type_error.integer)
b
value is not a valid float (type=type_error.float)
c
str type expected (type=type_error.str)
'''
标签:__,name,default,模型,BaseModel,import,class,pydantic 来源: https://www.cnblogs.com/puffer/p/16377532.html