Pydantic - 动态创建具有多个基类的模型?

ckn*_*oll 6 python multiple-inheritance pydantic

pydantic 文档中我明白了这一点:

import pydantic

class User(pydantic.BaseModel):
    id: int
    name: str

class Student(pydantic.BaseModel):
    semester: int

# this works as expected
class Student_User(User, Student):
    building: str

print(Student_User.__fields__.keys())
#> dict_keys(['semester', 'id', 'name', 'building'])
Run Code Online (Sandbox Code Playgroud)

但是,当我想动态创建类似的对象时(遵循动态模型创建部分):

# this results in a TypeError
pydantic.create_model("Student_User2", __base__=(User, Student))
Run Code Online (Sandbox Code Playgroud)

我得到:

TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
Run Code Online (Sandbox Code Playgroud)

问题:如何动态创建一个类Student_User

Ori*_*iFl 6

这不是原始问题的答案,但如果您像我一样并且您关心的只是拥有一个包含其他模型字段的模型,那么这应该是一个解决方案。

Student_User = pydantic.create_model("Student_User", **{
    **{key: (value.type_, value.default) for key, value in User.__fields__.items()},
    **{key: (value.type_, value.default) for key, value in Student.__fields__.items()},
    **{"building": (str, '')},
})

Run Code Online (Sandbox Code Playgroud)

本质上,我们正在动态创建一个新的 pydantic 模型,并将其字段设置为其他模型的字段加上一个额外的自定义字段。

注意:OP 在他的问题中包含了这些行:

print(Student_User.__fields__.keys())
#> dict_keys(['semester', 'id', 'name', 'building'])
Run Code Online (Sandbox Code Playgroud)

所以,我的猜测是,他的最终目标是复制其他模型中的字段,并且从多个基础创建模型只是实现它的一种方法。


Yux*_*hen 5

作为pydantic==1.9.2

Student_User2 = pydantic.create_model("Student_User2", __base__=(User, Student), building=(str, ...))
Run Code Online (Sandbox Code Playgroud)

运行成功并且

print(Student_User2.__fields__.keys())
Run Code Online (Sandbox Code Playgroud)

回报

dict_keys(['semester', 'id', 'name', 'building'])
Run Code Online (Sandbox Code Playgroud)