在pydantic中,core_schema.json_or_python_schema的json_schema属性用于什么

tpxzln5u  于 6个月前  发布在  Python
关注(0)|答案(1)|浏览(78)

假设我有一个外部类OriginalExternalClass,它的代码不能被修改。我想使用这个外部类作为另一个名为PydanticClassWithExternalClassMember的类的字段,这个类派生自pydantic BaseModel
我想避免使用任意类型标志,因为我想为OriginalExternalClass字段实现类型检查和序列化功能。To code的工作原理如下:

from typing import Any
from pydantic_core import core_schema
import pydantic

class OriginalExternalClass:
    def __init__(self, a: int, b: str) -> None:
        self.a = a
        self.b = b

class PydanticExternalClass(OriginalExternalClass):
    @classmethod
    def __get_pydantic_core_schema__(
        cls,
        _source_type: Any,
        _handler: pydantic.GetCoreSchemaHandler,
    ) -> core_schema.CoreSchema:
        def json_schema(value: dict) -> OriginalExternalClass:
            # NEVER CALLED!!!
            print("json_schema called")
            result = OriginalExternalClass(**value)

            return result

        def python_schema(
            value: OriginalExternalClass,
        ) -> OriginalExternalClass:
            print("python_schema called")
            if isinstance(value, dict):
                value = OriginalExternalClass(**value)

            if not isinstance(value, OriginalExternalClass):
                raise pydantic.ValidationError(
                    msg="Expected a `ExternalClass` instance",
                    loc=("third_party_type",),
                    type=OriginalExternalClass,
                )

            return value

        def serialization(value: OriginalExternalClass) -> dict:
            print("serialization called")
            return {"a": value.a, "b": value.b}

        return core_schema.json_or_python_schema(
            json_schema=core_schema.no_info_plain_validator_function(json_schema),
            python_schema=core_schema.no_info_plain_validator_function(python_schema),
            serialization=core_schema.plain_serializer_function_ser_schema(
                serialization
            ),
        )

class PydanticClassWithExternalClassMember(pydantic.BaseModel):
    x: PydanticExternalClass

字符串
然而,我不明白的是,json_schema=core_schema.no_info_plain_validator_function(json_schema)生成的JsonOrPythonSchemajson_schema属性是什么时候使用的?它需要做什么?函数json_schema在执行时从未被调用:

print(
    "m1 = PydanticClassWithExternalClassMember(x=PydanticExternalClass(1, 'basgsadf'))"
)
m1 = PydanticClassWithExternalClassMember(x=PydanticExternalClass(1, "basgsadf"))
print("d = m1.model_dump()")
d = m1.model_dump()
print("m1 = PydanticClassWithExternalClassMember(**d)")
m1 = PydanticClassWithExternalClassMember(**d)


并且输出是

m1 = PydanticClassWithExternalClassMember(x=PydanticExternalClass(1, 'basgsadf'))
python_schema called
d = m1.model_dump()
serialization called
m1 = PydanticClassWithExternalClassMember(**d)
python_schema called

eiee3dmh

eiee3dmh1#

这是因为你没有在那里测试JSON的语法化。
如果你这样做了:

adapter = pydantic.TypeAdapter(PydanticClassWithExternalClassMember)
value = adapter.validate_json("""{"x": {"a": 1, "b": "basgsadf"}}""")
print("Got", value.model_dump())

字符串
..

m1 = PydanticClassWithExternalClassMember(x=PydanticExternalClass(1, 'basgsadf'))
python_schema called
json_schema called
serialization called
Got {'x': {'a': 1, 'b': 'basgsadf'}}
d = m1.model_dump()
serialization called
m1 = PydanticClassWithExternalClassMember(**d)
python_schema called

相关问题