FastAPI学习笔记(一)-2.初识Pydantic

一、使用Python的类型注释type hints 来进行数据校验 和 setting管理。
FastAPI学习笔记(一)-2.初识Pydantic
 1 '''
 2 @author:invoker
 3 @project:fastapi202108
 4 @file: pydantic_tutorial.py
 5 @contact:invoker2021@126.com
 6 @descript:
 7 @Date:2021/8/4 18:05
 8 @version: Python 3.7.8
 9 '''
10 
11 """
12 一、使用Python的类型注释type hints 来进行数据校验 和 setting管理。
13 二、Pydantic可以在代码运行时提供类型提示,数据校验失败时提供友好的错误提示
14 三、定义输入应该如何在纯规范的Python代码中保存,并用Pydantic验证他。
15 """
16 
17 from pydantic import BaseModel
18 from datetime import datetime
19 from typing import List
20 from typing import Optional
21 
22 print("\033[31m1. -----Pydantic的基本用法------------------\033[0m")
23 
24 
25 class User(BaseModel):
26     id: int  # 没有给默认值则是必填字段
27     name: str = "John snow"  # 有默认值则是选填字段
28     signup_ts: Optional[datetime] = None  # 使用Optional表示是选填字段,不填就是None
29     friends: List[int] = []  # 列表中元素是int类型或则可以直接转换成int类型
30 
31 
32 external_data = {
33     "id": '1',
34     "signup_ts": "2021-08-04 18:00",
35     "friends": [1, 2, "3"]  # "3"可以int("3")的
36 }
37 
38 # python的解包,将字典的值分别赋值给对象中的属性
39 user = User(**external_data)
40 # 每个字段单独输出
41 print(user.id, user.name, user.signup_ts, user.friends)
42 # 时间字段按照原类型输出
43 print(repr(user.signup_ts))
44 # 将该对象以字典方式输出
45 print(user.dict())
View Code
执行结果:

FastAPI学习笔记(一)-2.初识Pydantic

 

 

 

二、Pydantic可以在代码运行时提供类型提示,数据校验失败时提供友好的错误提示
FastAPI学习笔记(一)-2.初识Pydantic
 1 '''
 2 @author:invoker
 3 @project:fastapi202108
 4 @file: pydantic_tutorial.py
 5 @contact:invoker2021@126.com
 6 @descript:
 7 @Date:2021/8/4 18:05
 8 @version: Python 3.7.8
 9 '''
10 
11 """
12 一、使用Python的类型注释type hints 来进行数据校验 和 setting管理。
13 二、Pydantic可以在代码运行时提供类型提示,数据校验失败时提供友好的错误提示
14 三、定义输入应该如何在纯规范的Python代码中保存,并用Pydantic验证他。
15 """
16 
17 from pydantic import BaseModel
18 from datetime import datetime
19 from typing import List
20 from typing import Optional
21 
22 print("\033[31m1. -----Pydantic的基本用法------------------\033[0m")
23 
24 
25 class User(BaseModel):
26     id: int  # 没有给默认值则是必填字段,非int型可以转换成int型
27     name: str = "John snow"  # 有默认值则是选填字段
28     signup_ts: Optional[datetime] = None  # 使用Optional表示是选填字段,不填就是None
29     friends: List[int] = []  # 列表中元素是int类型或则可以直接转换成int类型
30 
31 
32 external_data = {
33     "id": 'a',
34     "signup_ts": "2021-08-04 18:00",
35     "friends": [1, 2, "3a"]  # "3"可以int("3")的
36 }
37 
38 # python的解包,将字典的值分别赋值给对象中的属性
39 user = User(**external_data)
40 # 每个字段单独输出
41 print(user.id, user.name, user.signup_ts, user.friends)
42 # 时间字段按照原类型输出
43 print(repr(user.signup_ts))
44 # 将该对象以字典方式输出
45 print(user.dict())
View Code

 


如果输入参数格式不正确。则会提示错误。

FastAPI学习笔记(一)-2.初识Pydantic

 

 

 

2.2 捕获异常
FastAPI学习笔记(一)-2.初识Pydantic
 1 '''
 2 @author:invoker
 3 @project:fastapi202108
 4 @file: pydantic_tutorial.py
 5 @contact:invoker2021@126.com
 6 @descript:
 7 @Date:2021/8/4 18:05
 8 @version: Python 3.7.8
 9 '''
10 
11 """
12 一、使用Python的类型注释type hints 来进行数据校验 和 setting管理。
13 二、Pydantic可以在代码运行时提供类型提示,数据校验失败时提供友好的错误提示
14 三、定义输入应该如何在纯规范的Python代码中保存,并用Pydantic验证他。
15 """
16 
17 from pydantic import BaseModel, ValidationError
18 from datetime import datetime
19 from typing import List
20 from typing import Optional
21 
22 print("\033[33;1m1. -----Pydantic的基本用法------------------\033[33;0m")
23 
24 
25 class User(BaseModel):
26     id: int  # 没有给默认值则是必填字段,非int型可以转换成int型
27     name: str = "John snow"  # 有默认值则是选填字段
28     signup_ts: Optional[datetime] = None  # 使用Optional表示是选填字段,不填就是None
29     friends: List[int] = []  # 列表中元素是int类型或则可以直接转换成int类型
30 
31 
32 external_data = {
33     "id": '1',
34     "signup_ts": "2021-08-04 18:00",
35     "friends": [1, 2, "3"]  # "3"可以int("3")的
36 }
37 
38 # python的解包,将字典的值分别赋值给对象中的属性
39 user = User(**external_data)
40 # 每个字段单独输出
41 print(user.id, user.name, user.signup_ts, user.friends)
42 # 时间字段按照原类型输出
43 print(repr(user.signup_ts))
44 # 将该对象以字典方式输出
45 print(user.dict())
46 
47 print("\033[33;1m2. -----------校验失败错误处理------------\033[33;0m")
48 
49 try:
50     User(id=1, signup_ts=datetime.today(), friends=[1, 2, 'not number'])
51 except ValidationError as e:
52     print(e.json())
View Code

FastAPI学习笔记(一)-2.初识Pydantic

 

 

 

三、BaseModel类的属性和方法
FastAPI学习笔记(一)-2.初识Pydantic
 1 '''
 2 @author:invoker
 3 @project:fastapi202108
 4 @file: pydantic_tutorial.py
 5 @contact:invoker2021@126.com
 6 @descript:
 7 @Date:2021/8/4 18:05
 8 @version: Python 3.7.8
 9 '''
10 
11 """
12 一、使用Python的类型注释type hints 来进行数据校验 和 setting管理。
13 二、Pydantic可以在代码运行时提供类型提示,数据校验失败时提供友好的错误提示
14 三、定义输入应该如何在纯规范的Python代码中保存,并用Pydantic验证他。
15 """
16 
17 from pydantic import BaseModel, ValidationError
18 from datetime import datetime
19 from typing import List
20 from typing import Optional
21 from pathlib import Path
22 
23 print("\033[33;1m1. -----Pydantic的基本用法------------------\033[33;0m")
24 
25 
26 class User(BaseModel):
27     id: int  # 没有给默认值则是必填字段,非int型可以转换成int型
28     name: str = "John snow"  # 有默认值则是选填字段
29     signup_ts: Optional[datetime] = None  # 使用Optional表示是选填字段,不填就是None
30     friends: List[int] = []  # 列表中元素是int类型或则可以直接转换成int类型
31 
32 
33 external_data = {
34     "id": '1',
35     "signup_ts": "2021-08-04 18:00",
36     "friends": [1, 2, "3"]  # "3"可以int("3")的
37 }
38 
39 # python的解包,将字典的值分别赋值给对象中的属性
40 user = User(**external_data)
41 # 每个字段单独输出
42 print(user.id, user.name, user.signup_ts, user.friends)
43 # 时间字段按照原类型输出
44 print(repr(user.signup_ts))
45 # 将该对象以字典方式输出
46 print(user.dict())
47 
48 print("\033[33;1m2. -----------校验失败错误处理------------\033[33;0m")
49 
50 try:
51     User(id=1, signup_ts=datetime.today(), friends=[1, 2, 'not number'])
52 except ValidationError as e:
53     print(e.json())
54 
55 print("\033[33;1m3. -----------BaseModel类的属性和方法------------\033[33;0m")
56 # 1.以字典格式输出
57 print(f'以字典格式输出:{user.dict()}')
58 print(f'type:{type(user.dict())}')  # dict
59 # 2.以json格式输出
60 print(f'以json格式输出:{user.json()}')
61 print(f'type:{type(user.json())}')  # str
62 # 3.浅拷贝
63 print(f'浅拷贝:{user.copy()}')
64 print(f'type:{type(user.copy())}')  # User
65 # 4.解析数据的方法
66 # 4.1
67 print(f'解析数据的方法1:{User.parse_obj(obj=external_data)}')
68 print(f'type{type(User.parse_obj(obj=external_data))}')  # User
69 # 4.2
70 print(f'解析数据方法2:{User(**external_data)}')
71 print(f'type:{type(User(**external_data))}')  # User
72 # 4.3
73 print(f'解析数据的方法3:解析规范的原生str数据')
74 print(User.parse_raw('{"id": 1, "name": "John snow", "signup_ts": "2021-08-04T18:00:00", "friends": [1, 2, 3]}'))
75 # 4.4 解析文件
76 print(f'解析数据的方法4:解析文件')
77 path = Path('pydantic_tutorial.json')
78 path.write_text('{"id": 1, "name": "John snow", "signup_ts": "2021-08-04T18:00:00", "friends": [1, 2, 3]}')
79 print(User.parse_file(path))
80 
81 # 5 数据格式
82 print(user.schema())
83 print(user.schema_json())
84 
85 # 6 construct 不校验数据创建BaseModel对象实例,此方法只在特殊场景使用。
86 user_data = {"id": 'error', "name": "John snow", "signup_ts": "2021-08-04T18:00:00", "friends": [1, 2, 3]}
87 print(user.construct(**user_data))
88 print(type(user.construct(**user_data)))
89 
90 # 7 字段顺序
91 print(User.__fields__.keys())  # 只要在定义模型类时,所有字段都注明类型,字段顺序就不会乱
View Code

FastAPI学习笔记(一)-2.初识Pydantic

 

 

 FastAPI学习笔记(一)-2.初识Pydantic

 

 

 

四、递归模型(嵌套:一个模型内调用另一个模型)

引用场景不太清楚???

FastAPI学习笔记(一)-2.初识Pydantic
  1 '''
  2 @author:invoker
  3 @project:fastapi202108
  4 @file: pydantic_tutorial.py
  5 @contact:invoker2021@126.com
  6 @descript:
  7 @Date:2021/8/4 18:05
  8 @version: Python 3.7.8
  9 '''
 10 
 11 """
 12 一、使用Python的类型注释type hints 来进行数据校验 和 setting管理。
 13 二、Pydantic可以在代码运行时提供类型提示,数据校验失败时提供友好的错误提示
 14 三、定义输入应该如何在纯规范的Python代码中保存,并用Pydantic验证他。
 15 """
 16 
 17 from pydantic import BaseModel, ValidationError
 18 from datetime import datetime, date
 19 from typing import List
 20 from typing import Optional
 21 from pathlib import Path
 22 
 23 print("\033[33;1m1. -----Pydantic的基本用法------------------\033[33;0m")
 24 
 25 
 26 class User(BaseModel):
 27     id: int  # 没有给默认值则是必填字段,非int型可以转换成int型
 28     name: str = "John snow"  # 有默认值则是选填字段
 29     signup_ts: Optional[datetime] = None  # 使用Optional表示是选填字段,不填就是None
 30     friends: List[int] = []  # 列表中元素是int类型或则可以直接转换成int类型
 31 
 32 
 33 external_data = {
 34     "id": '1',
 35     "signup_ts": "2021-08-04 18:00",
 36     "friends": [1, 2, "3"]  # "3"可以int("3")的
 37 }
 38 
 39 # python的解包,将字典的值分别赋值给对象中的属性
 40 user = User(**external_data)
 41 # 每个字段单独输出
 42 print(user.id, user.name, user.signup_ts, user.friends)
 43 # 时间字段按照原类型输出
 44 print(repr(user.signup_ts))
 45 # 将该对象以字典方式输出
 46 print(user.dict())
 47 
 48 print("\033[33;1m2. -----------校验失败错误处理------------\033[33;0m")
 49 
 50 try:
 51     User(id=1, signup_ts=datetime.today(), friends=[1, 2, 'not number'])
 52 except ValidationError as e:
 53     print(e.json())
 54 
 55 print("\033[33;1m3. -----------BaseModel类的属性和方法------------\033[33;0m")
 56 # 1.以字典格式输出
 57 print(f'以字典格式输出:{user.dict()}')
 58 print(f'type:{type(user.dict())}')  # dict
 59 # 2.以json格式输出
 60 print(f'以json格式输出:{user.json()}')
 61 print(f'type:{type(user.json())}')  # str
 62 # 3.浅拷贝
 63 print(f'浅拷贝:{user.copy()}')
 64 print(f'type:{type(user.copy())}')  # User
 65 # 4.解析数据的方法
 66 # 4.1
 67 print(f'解析数据的方法1:{User.parse_obj(obj=external_data)}')
 68 print(f'type{type(User.parse_obj(obj=external_data))}')  # User
 69 # 4.2
 70 print(f'解析数据方法2:{User(**external_data)}')
 71 print(f'type:{type(User(**external_data))}')  # User
 72 # 4.3
 73 print(f'解析数据的方法3:解析规范的原生str数据')
 74 print(User.parse_raw('{"id": 1, "name": "John snow", "signup_ts": "2021-08-04T18:00:00", "friends": [1, 2, 3]}'))
 75 # 4.4 解析文件
 76 print(f'解析数据的方法4:解析文件')
 77 path = Path('pydantic_tutorial.json')
 78 path.write_text('{"id": 1, "name": "John snow", "signup_ts": "2021-08-04T18:00:00", "friends": [1, 2, 3]}')
 79 print(User.parse_file(path))
 80 
 81 # 5 数据格式
 82 print(user.schema())
 83 print(user.schema_json())
 84 
 85 # 6 construct 不校验数据创建BaseModel对象实例,此方法只在特殊场景使用。
 86 user_data = {"id": 'error', "name": "John snow", "signup_ts": "2021-08-04T18:00:00", "friends": [1, 2, 3]}
 87 print(user.construct(**user_data))
 88 print(type(user.construct(**user_data)))
 89 
 90 # 7 字段顺序
 91 print(User.__fields__.keys())  # 只要在定义模型类时,所有字段都注明类型,字段顺序就不会乱
 92 
 93 print("\033[33;1m4. -----------递归模型(嵌套:在一个模型内调用另一个模型)------------\033[33;0m")
 94 
 95 
 96 class Sound(BaseModel):
 97     sound: str
 98 
 99 
100 class Dog(BaseModel):
101     birthday: date
102     weight2: Optional[float] = None
103     sound: List[Sound]
104 
105 dogs = Dog(birthday=date.today(),  weight2=2.22, sound=[{"sound": "wang!"}, {"sound": "o!"}])
106 print(dogs.dict())
View Code

 

FastAPI学习笔记(一)-2.初识Pydantic

 

 

 如果传入值是sound1,则会报错

FastAPI学习笔记(一)-2.初识Pydantic
  1 '''
  2 @author:invoker
  3 @project:fastapi202108
  4 @file: pydantic_tutorial.py
  5 @contact:invoker2021@126.com
  6 @descript:
  7 @Date:2021/8/4 18:05
  8 @version: Python 3.7.8
  9 '''
 10 
 11 """
 12 一、使用Python的类型注释type hints 来进行数据校验 和 setting管理。
 13 二、Pydantic可以在代码运行时提供类型提示,数据校验失败时提供友好的错误提示
 14 三、定义输入应该如何在纯规范的Python代码中保存,并用Pydantic验证他。
 15 """
 16 
 17 from pydantic import BaseModel, ValidationError
 18 from datetime import datetime, date
 19 from typing import List
 20 from typing import Optional
 21 from pathlib import Path
 22 
 23 print("\033[33;1m1. -----Pydantic的基本用法------------------\033[33;0m")
 24 
 25 
 26 class User(BaseModel):
 27     id: int  # 没有给默认值则是必填字段,非int型可以转换成int型
 28     name: str = "John snow"  # 有默认值则是选填字段
 29     signup_ts: Optional[datetime] = None  # 使用Optional表示是选填字段,不填就是None
 30     friends: List[int] = []  # 列表中元素是int类型或则可以直接转换成int类型
 31 
 32 
 33 external_data = {
 34     "id": '1',
 35     "signup_ts": "2021-08-04 18:00",
 36     "friends": [1, 2, "3"]  # "3"可以int("3")的
 37 }
 38 
 39 # python的解包,将字典的值分别赋值给对象中的属性
 40 user = User(**external_data)
 41 # 每个字段单独输出
 42 print(user.id, user.name, user.signup_ts, user.friends)
 43 # 时间字段按照原类型输出
 44 print(repr(user.signup_ts))
 45 # 将该对象以字典方式输出
 46 print(user.dict())
 47 
 48 print("\033[33;1m2. -----------校验失败错误处理------------\033[33;0m")
 49 
 50 try:
 51     User(id=1, signup_ts=datetime.today(), friends=[1, 2, 'not number'])
 52 except ValidationError as e:
 53     print(e.json())
 54 
 55 print("\033[33;1m3. -----------BaseModel类的属性和方法------------\033[33;0m")
 56 # 1.以字典格式输出
 57 print(f'以字典格式输出:{user.dict()}')
 58 print(f'type:{type(user.dict())}')  # dict
 59 # 2.以json格式输出
 60 print(f'以json格式输出:{user.json()}')
 61 print(f'type:{type(user.json())}')  # str
 62 # 3.浅拷贝
 63 print(f'浅拷贝:{user.copy()}')
 64 print(f'type:{type(user.copy())}')  # User
 65 # 4.解析数据的方法
 66 # 4.1
 67 print(f'解析数据的方法1:{User.parse_obj(obj=external_data)}')
 68 print(f'type{type(User.parse_obj(obj=external_data))}')  # User
 69 # 4.2
 70 print(f'解析数据方法2:{User(**external_data)}')
 71 print(f'type:{type(User(**external_data))}')  # User
 72 # 4.3
 73 print(f'解析数据的方法3:解析规范的原生str数据')
 74 print(User.parse_raw('{"id": 1, "name": "John snow", "signup_ts": "2021-08-04T18:00:00", "friends": [1, 2, 3]}'))
 75 # 4.4 解析文件
 76 print(f'解析数据的方法4:解析文件')
 77 path = Path('pydantic_tutorial.json')
 78 path.write_text('{"id": 1, "name": "John snow", "signup_ts": "2021-08-04T18:00:00", "friends": [1, 2, 3]}')
 79 print(User.parse_file(path))
 80 
 81 # 5 数据格式
 82 print(user.schema())
 83 print(user.schema_json())
 84 
 85 # 6 construct 不校验数据创建BaseModel对象实例,此方法只在特殊场景使用。
 86 user_data = {"id": 'error', "name": "John snow", "signup_ts": "2021-08-04T18:00:00", "friends": [1, 2, 3]}
 87 print(user.construct(**user_data))
 88 print(type(user.construct(**user_data)))
 89 
 90 # 7 字段顺序
 91 print(User.__fields__.keys())  # 只要在定义模型类时,所有字段都注明类型,字段顺序就不会乱
 92 
 93 print("\033[33;1m4. -----------递归模型(嵌套:在一个模型内调用另一个模型)------------\033[33;0m")
 94 
 95 
 96 class Sound(BaseModel):
 97     sound: str
 98 
 99 
100 class Dog(BaseModel):
101     birthday: date
102     weight2: Optional[float] = None
103     sound: List[Sound]
104 
105 dogs = Dog(birthday=date.today(),  weight2=2.22, sound=[{"sound1": "wang!"}, {"sound": "o!"}])
106 print(dogs.dict())
View Code

FastAPI学习笔记(一)-2.初识Pydantic

 

 

 五、创建ORM模型

FastAPI学习笔记(一)-2.初识Pydantic
 1 '''
 2 @author:invoker
 3 @project:fastapi202108
 4 @file: orm.py
 5 @contact:invoker2021@126.com
 6 @descript:
 7 @Date:2021/8/5 10:21
 8 @version: Python 3.7.8
 9 '''
10 # SQLAlchemy==1.3.22
11 from sqlalchemy import Column, Integer, String
12 from sqlalchemy.dialects.postgresql import ARRAY
13 from sqlalchemy.ext.declarative import declarative_base
14 # pydantic==1.7.3
15 from pydantic import BaseModel, constr
16 # python自带类型
17 from typing import List
18 
19 print("\033[33;1m1. -----------------ORM模型:从类实例创建ORM对象的模型------------------\033[33;0m")
20 
21 Base = declarative_base()
22 
23 
24 class CompanyOrm(Base):
25     __tablename__ = "companies"
26     id = Column(Integer, primary_key=True, nullable=False)
27     public_key = Column(String(20), index=True, nullable=False, unique=True)
28     name = Column(String(63), unique=True)
29     domains = Column(ARRAY(String(255)))
30 
31 
32 class CompanyMode(BaseModel):
33     id: int
34     public_key: constr(max_length=20)
35     name: constr(max_length=63)
36     domains: List[constr(max_length=255)]
37 
38     class Config:
39         orm_mode = True
40 
41 
42 co_orm = CompanyOrm(
43     id=123,
44     public_key='foobar',
45     name='testing',
46     domains=['invoker.com', 'test.com']
47 )
48 
49 print(CompanyMode.from_orm(co_orm))
50 print(type(CompanyMode.from_orm(co_orm)))
View Code

FastAPI学习笔记(一)-2.初识Pydantic

 

 FastAPI学习笔记(一)-2.初识Pydantic

 

 

上一篇:fastapi二:数据模型与验证-pydantic


下一篇:Core Data & MagicalRecord