python Pydantic ORM模式到底是做什么的?

dhxwm5r4  于 2023-01-24  发布在  Python
关注(0)|答案(1)|浏览(539)

根据文档,需要Pydantic“ORM模式”(在Config中使用orm_mode = True启用)来启用from_orm方法,以便通过从另一个类示例阅读属性来创建模型示例。如果未启用ORM模式,则from_orm方法将引发异常。
我的疑虑是:
1.启用ORM模式是否有任何其他影响(功能、性能等方面)?
1.如果不是,为什么它是一个选择加入的功能?

py49o6xq

py49o6xq1#

幸运的是,至少第一个问题可以相当容易地回答。
1.10.4版本开始,只有两个地方(插件除外)可以使用orm_mode

BaseModel.from_orm

这基本上是一个替代构造函数。它放弃了常规的__init__方法,而采用了稍微不同的设置。不确定为什么要这样设计。但是必须设置orm_mode标志,这样该方法才不会引发错误。很简单。我在这里没有看到隐藏的惊喜。

BaseModel.validate

此方法是BaseModel类型的默认验证器。如果没有orm_mode标志,则验证器期望的值为1)特定模型的示例,2)可以解包到该模型的构造函数中的字典,或者3)可以 * 强制 * 到字典,然后解包到该模型的构造函数中的内容。
如果orm_modeTrue,并且验证器遇到的东西 * 不是 * 模型的示例,* 也不是 * 字典,那么它会假设它是一个可以传递给前面提到的from_orm方法的对象,并调用它,而不是尝试dict强制。
请注意,在初始化过程中不调用此方法,如果将某个值赋给非BaseModel的任何类型的模型字段,则不调用此方法。(并且用作数据输入的对象也是嵌套的),也就是说,一个模型有一个用另一个模型注解的字段,只有这样,外部模型才会调用内部模型的validate方法。
请考虑以下几点:

from __future__ import annotations
from typing import TypeVar

from pydantic import BaseModel

M = TypeVar("M", bound=BaseModel)

class Foo(BaseModel):
    x: int

    @classmethod
    def validate(cls: type[M], value: object) -> M:
        print("called `Foo.validate`")
        return super().validate(value)

    class Config:
        orm_mode = True

class A:
    x = 1

foo = Foo.from_orm(A)
print(foo.json())

输出为{"x": 1},我们看到Foo.validate没有被调用。
现在我们对此进行一些扩展:

...

class Bar(BaseModel):
    f: Foo

    class Config:
        orm_mode = True

class B:
    f = A

bar = Bar.from_orm(B)
print(bar.json())

新输出:

called `Foo.validate`
{"f": {"x": 1}}

现在验证器按预期被调用了,如果我们将类似的print语句注入到Foo.from_orm中,我们将看到它也被调用了,当我们在Foo.validate被调用之后立即调用Bar.from_orm时。
这在某些特定的情况下可能是相关的,但一般来说,我认为在验证过程中级联应用from_orm是有意义的,并且应该适应主要的预期用例--数据库ORM对象。
如果您希望在验证过程中有不同的行为,您可以定义自己的validator方法,甚至简单地覆盖validate方法(取决于您的用例)。
在源代码中没有orm_mode的其他用途,所以就功能而言就是这样。
性能在IMO环境中并不重要,因为它只是一种完全不同的初始化模型示例的方法。除非你想知道首先手动将ORM对象转换为字典并将其传递给parse_obj或直接在其上调用from_orm是否更快。不过你可以相当容易地对它进行基准测试。
在我看来,BaseModel的其他功能不会受到该配置设置的任何影响(性能方面)。
对于你的第二个问题,我只能猜测。所以我将避免回答。有一个issue已经开放了一段时间,建议完全删除设置,这似乎是一种符合你的推理,它不应该是"opt-in"在任何情况下。我不知道如果塞缪尔科尔文仍然接受向后兼容的功能请求的v2。但是这个问题还没有得到很大的关注,你可能想参加那里。

相关问题