Ник*_*та 5 python json pydantic
我创建了 Pydantic 模型。但它不转换并输出错误请告诉我,出了什么问题。
classDTO:
from pydantic import BaseModel,Field
from typing import List,Dict
from datetime import date
class OurBaseModel(BaseModel):
pass
#class Config:
#orm_mode = True
class SessionSubjectDTO(OurBaseModel):
edu_year: int
semester_type: str
class MarkDTO(OurBaseModel):
semester_number: int
subject_name: str
control_type: str
mark: str # or int
session_subject: SessionSubjectDTO #= Field(None, alias="SessionSubjectDTO")
class MarksDTO(OurBaseModel):
__root__: List[MarkDTO]
class AttestationDTO(BaseModel):
subject_name: str
value: int
attestation_start_date: date
class AttestationsDTO(OurBaseModel):
__root__: List[AttestationDTO]
class DebtDTO(OurBaseModel):
semester_number: int
subject_name: str
control_type: str
session_subject: SessionSubjectDTO #= Field(None, alias="SessionSubjectDTO")
class DebtsDTO(OurBaseModel):
__root__: List[DebtDTO]
class SkipDTO(OurBaseModel):
valid: int
no_valid: int
attestation_start_date: date
class SkipsDTO(OurBaseModel):
__root__: List[SkipDTO]
class StudentDTO(OurBaseModel):
uid: str
marks: MarksDTO
attestations: AttestationsDTO
debts: DebtsDTO
skips: SkipsDTO
class StudentsDTO(OurBaseModel):
__root__: List[StudentDTO]
Run Code Online (Sandbox Code Playgroud)
example.json:
[
{
"uid": "61c689ac-98a1-11e9-8198-4ccc6a2d123b",
"marks": [
{
"semester_number": 1,
"subject_name": "454",
"control_type": "5",
"mark": "3.",
"date": "2019-12-27",
"session_subject": {
"id": 4228,
"edu_year": 2019,
"semester_type": "1"
}
}
],
"attestations": [
{
"subject_name": "133",
"value": 2,
"attestation_start_date": "2019-10-07",
"attestation_end_date": "2019-10-12"
}
],
"debts": [
{
"semester_number": 4,
"subject_name": "323",
"control_type": "12",
"session_subject": {
"id": 22856,
"edu_year": 2020,
"semester_type": "20"
}
}
],
"skips": [
{
"valid": null,
"no_valid": null,
"attestation_start_date": "2020-03-09",
"attestation_end_date": "2020-03-14"
}
]
}
]
Run Code Online (Sandbox Code Playgroud)
main.py:
students = pydantic.parse_file_as(path='192.json', type_=classDTO.StudentsDTO)
Run Code Online (Sandbox Code Playgroud)
错误:
Traceback (most recent call last):
File "main.py", line 73, in <module>
students = pydantic.parse_file_as(path='192.json', type_=classDTO.StudentsDTO)
File "pydantic\tools.py", line 60, in pydantic.tools.parse_file_as
File "pydantic\tools.py", line 38, in pydantic.tools.parse_obj_as
File "pydantic\main.py", line 331, in pydantic.main.BaseModel.__init__
pydantic.error_wrappers.ValidationError: 424 validation errors for ParsingModel[StudentsDTO]
__root__ -> __root__ -> 0 -> attestations -> __root__ -> 18 -> value
none is not an allowed value (type=type_error.none.not_allowed)
__root__ -> __root__ -> 0 -> attestations -> __root__ -> 19 -> value
none is not an allowed value (type=type_error.none.not_allowed)
__root__ -> __root__ -> 0 -> attestations -> __root__ -> 20 -> value
none is not an allowed value (type=type_error.none.not_allowed)
...
__root__ -> __root__ -> 16 -> skips -> __root__ -> 1 -> no_valid
none is not an allowed value (type=type_error.none.not_allowed)
Run Code Online (Sandbox Code Playgroud)
我尝试使用自定义根类型解决问题:
Pydantic 模型可以通过声明字段来定义自定义根类型。
__root__根类型可以是 pydantic 支持的任何类型,并由字段上的类型提示指定
__root__。根值可以__init__通过__root__关键字参数传递给模型,或者作为 的第一个也是唯一的参数parse_obj。
您中的数据example.json似乎并没有导致所有错误,而只是导致了一些错误。
原因如下:
SkipDTO例如,在您的 中,您正在定义一个no_valid: int字段。
根据这个定义,该字段是必需的,这就是为什么它不能是null/ None。
但是,您正在传递:
...
"skips": [
{
"valid": null,
"no_valid": null,
"attestation_start_date": "2020-03-09",
"attestation_end_date": "2020-03-14"
}
]
...
Run Code Online (Sandbox Code Playgroud)
如果是(和)null的有效值,那么您需要将模型调整为以下内容:no_validvalid
from typing import List, Dict, Optional
class SkipDTO(OurBaseModel):
valid: Optional[int]
no_valid: Optional[int]
attestation_start_date: date
Run Code Online (Sandbox Code Playgroud)
如果传入一个值Optional,则会设置一个字段。Nonenull
您模型中的其他字段可能也是如此AttestationDTO.value。
| 归档时间: |
|
| 查看次数: |
21848 次 |
| 最近记录: |