使用动态键创建 Pydantic 模型模式
Creating Pydantic Model Schema with Dynamic Key
我正在尝试为以下 JSON 实施 Pydantic 模式模型。
{
"description": "Best Authors And Their Books",
"authorInfo":
{
"KISHAN":
{
"numberOfBooks": 10,
"bestBookIds": [0, 2, 3, 7]
},
"BALARAM":
{
"numberOfBooks": 15,
"bestBookIds": [10, 12, 14]
},
"RAM":
{
"numberOfBooks": 6,
"bestBookIds": [3,5]
}
}
}
这是 Pydantic 中的模式对象
from typing import List, Type, Dict
from pydantic import BaseModel
class AuthorBookDetails(BaseModel):
numberOfBooks: int
bestBookIds: List[int]
class AuthorInfoCreate(BaseModel):
__root__: Dict[str, Type[AuthorBookDetails]]
#pass
class ScreenCreate(BaseModel):
description: str
authorInfo: Type[AuthorInfoCreate]
我正在按如下方式解析 AuthorInfoCreate:
y = AuthorBookDetails( numberOfBooks = 10, bestBookIds = [3,5])
print(y)
print(type(y))
x = AuthorInfoCreate.parse_obj({"RAM" : y})
print(x)
我看到以下错误。
numberOfBooks=10 bestBookIds=[3, 5]
<class '__main__.AuthorBookDetails'>
Traceback (most recent call last):
File "test.py", line 44, in <module>
x = AuthorInfoCreate.parse_obj({"RAM": y})
File "C:\sources\rep-funds\env\lib\site-packages\pydantic\main.py", line 402, in parse_obj
return cls(**obj)
File "C:\sources\rep-funds\env\lib\site-packages\pydantic\main.py", line 283, in __init__
raise validation_error
pydantic.error_wrappers.ValidationError: 1 validation error for AuthorInfoCreate
__root__ -> RAM
subclass of AuthorBookDetails expected (type=type_error.subclass; expected_class=AuthorBookDetails)
我想了解如何更改 AuthorInfoCreate 以便提及 json 架构。
实际上,您应该从类型注释中删除 Type。您需要 class 的实例,而不是实际的 class。尝试以下解决方案:
from typing import List,Dict
from pydantic import BaseModel
class AuthorBookDetails(BaseModel):
numberOfBooks: int
bestBookIds: List[int]
class AuthorInfoCreate(BaseModel):
__root__: Dict[str, AuthorBookDetails]
class ScreenCreate(BaseModel):
description: str
authorInfo: AuthorInfoCreate
对于那些知道如何初始化 Pydantic 类 的人,@SKhalymon 给出了答案,
from typing import List, Dict
from pydantic import BaseModel
class AuthorBookDetails(BaseModel):
numberOfBooks: int
bestBookIds: List[int]
class AuthorInfoCreate(BaseModel):
__root__: Dict[str, AuthorBookDetails]
class ScreenCreate(BaseModel):
description: str
authorInfo: AuthorInfoCreate
kishan = AuthorBookDetails( numberOfBooks = 10, bestBookIds = [0, 2, 3, 7])
balram = AuthorBookDetails( numberOfBooks = 15, bestBookIds = [10, 12, 14])
ram = AuthorBookDetails( numberOfBooks = 6, bestBookIds = [3, 5])
aic = AuthorInfoCreate(__root__={"KISHAN": kishan, "BALRAM": balram, "RAM": ram})
sc = ScreenCreate( description = "Best Authors And Their Books", authorInfo = aic)
print(sc.json())
输出:
{"description": "Best Authors And Their Books", "authorInfo": {"__root__": {"KISHAN": {"numberOfBooks": 10, "bestBookIds": [0, 2, 3, 7]}, "BALRAM": {"numberOfBooks": 15, "bestBookIds": [10, 12, 14]}, "RAM": {"numberOfBooks": 6, "bestBookIds": [3, 5]}}}}
__root__
is only supported at parent level.
这就是为什么不能使用
class AuthorInfoCreate(BaseModel):
__root__: Dict[str, AuthorBookDetails]
针对上述问题提出了以下解决方法
from typing import Any, Dict, List
from pydantic import BaseModel as PydanticBaseModel
from pydantic.utils import ROOT_KEY
class BaseModel(PydanticBaseModel):
def __init__(__pydantic_self__, **data: Any) -> None:
if __pydantic_self__.__custom_root_type__ and data.keys() != {ROOT_KEY}:
data = {ROOT_KEY: data}
super().__init__(**data)
...
...
现在可以正常使用 AuthorInfoCreate
模型
aic = AuthorInfoCreate(**{"KISHAN": kishan, "BALRAM": balram, "RAM": ram})
PR #2237 应该不需要上述解决方法。
我正在尝试为以下 JSON 实施 Pydantic 模式模型。
{
"description": "Best Authors And Their Books",
"authorInfo":
{
"KISHAN":
{
"numberOfBooks": 10,
"bestBookIds": [0, 2, 3, 7]
},
"BALARAM":
{
"numberOfBooks": 15,
"bestBookIds": [10, 12, 14]
},
"RAM":
{
"numberOfBooks": 6,
"bestBookIds": [3,5]
}
}
}
这是 Pydantic 中的模式对象
from typing import List, Type, Dict
from pydantic import BaseModel
class AuthorBookDetails(BaseModel):
numberOfBooks: int
bestBookIds: List[int]
class AuthorInfoCreate(BaseModel):
__root__: Dict[str, Type[AuthorBookDetails]]
#pass
class ScreenCreate(BaseModel):
description: str
authorInfo: Type[AuthorInfoCreate]
我正在按如下方式解析 AuthorInfoCreate:
y = AuthorBookDetails( numberOfBooks = 10, bestBookIds = [3,5])
print(y)
print(type(y))
x = AuthorInfoCreate.parse_obj({"RAM" : y})
print(x)
我看到以下错误。
numberOfBooks=10 bestBookIds=[3, 5]
<class '__main__.AuthorBookDetails'>
Traceback (most recent call last):
File "test.py", line 44, in <module>
x = AuthorInfoCreate.parse_obj({"RAM": y})
File "C:\sources\rep-funds\env\lib\site-packages\pydantic\main.py", line 402, in parse_obj
return cls(**obj)
File "C:\sources\rep-funds\env\lib\site-packages\pydantic\main.py", line 283, in __init__
raise validation_error
pydantic.error_wrappers.ValidationError: 1 validation error for AuthorInfoCreate
__root__ -> RAM
subclass of AuthorBookDetails expected (type=type_error.subclass; expected_class=AuthorBookDetails)
我想了解如何更改 AuthorInfoCreate 以便提及 json 架构。
实际上,您应该从类型注释中删除 Type。您需要 class 的实例,而不是实际的 class。尝试以下解决方案:
from typing import List,Dict
from pydantic import BaseModel
class AuthorBookDetails(BaseModel):
numberOfBooks: int
bestBookIds: List[int]
class AuthorInfoCreate(BaseModel):
__root__: Dict[str, AuthorBookDetails]
class ScreenCreate(BaseModel):
description: str
authorInfo: AuthorInfoCreate
对于那些知道如何初始化 Pydantic 类 的人,@SKhalymon 给出了答案,
from typing import List, Dict
from pydantic import BaseModel
class AuthorBookDetails(BaseModel):
numberOfBooks: int
bestBookIds: List[int]
class AuthorInfoCreate(BaseModel):
__root__: Dict[str, AuthorBookDetails]
class ScreenCreate(BaseModel):
description: str
authorInfo: AuthorInfoCreate
kishan = AuthorBookDetails( numberOfBooks = 10, bestBookIds = [0, 2, 3, 7])
balram = AuthorBookDetails( numberOfBooks = 15, bestBookIds = [10, 12, 14])
ram = AuthorBookDetails( numberOfBooks = 6, bestBookIds = [3, 5])
aic = AuthorInfoCreate(__root__={"KISHAN": kishan, "BALRAM": balram, "RAM": ram})
sc = ScreenCreate( description = "Best Authors And Their Books", authorInfo = aic)
print(sc.json())
输出:
{"description": "Best Authors And Their Books", "authorInfo": {"__root__": {"KISHAN": {"numberOfBooks": 10, "bestBookIds": [0, 2, 3, 7]}, "BALRAM": {"numberOfBooks": 15, "bestBookIds": [10, 12, 14]}, "RAM": {"numberOfBooks": 6, "bestBookIds": [3, 5]}}}}
__root__
is only supported at parent level.
这就是为什么不能使用
class AuthorInfoCreate(BaseModel):
__root__: Dict[str, AuthorBookDetails]
针对上述问题提出了以下解决方法
from typing import Any, Dict, List from pydantic import BaseModel as PydanticBaseModel from pydantic.utils import ROOT_KEY class BaseModel(PydanticBaseModel): def __init__(__pydantic_self__, **data: Any) -> None: if __pydantic_self__.__custom_root_type__ and data.keys() != {ROOT_KEY}: data = {ROOT_KEY: data} super().__init__(**data) ... ...
现在可以正常使用 AuthorInfoCreate
模型
aic = AuthorInfoCreate(**{"KISHAN": kishan, "BALRAM": balram, "RAM": ram})
PR #2237 应该不需要上述解决方法。