如何解决pydantic 转换为 jsonable dict不是完整的 json 字符串
我想使用 pydantic
来处理 api 和数据存储之间的数据(双向),因为它很好地支持我关心的几种类型,这些类型本身不是 json 可序列化的。它比当前方法具有更好的读取/验证支持,但我还需要创建 json-serializable dict
对象来写出。
from uuid import UUID,uuid4
from pydantic import BaseModel
class Model(BaseModel):
the_id: UUID
instance = Model(the_id=uuid4())
print("1: %s" % instance.dict()
print("2: %s" % instance.json()
印刷品
{'the_id': UUID('4108356a-556e-484b-9447-07b56a664763')}
>>> inst.json()
'{"the_id": "4108356a-556e-484b-9447-07b56a664763"}'
我喜欢以下内容:
{"the_id": "4108356a-556e-484b-9447-07b56a664763"} # eg "json-compatible" dict
看来,虽然pydantic 拥有所有映射,但我在json
中的标准json.dumps( ... default=pydantic_encoder)
~递归编码器(pydantic/main.py
) 之外找不到任何序列化用法。但我更愿意保留一个库来验证 raw->obj(pydantic 在这方面很棒)以及 obj->raw(dict) 这样我就不必管理多个序列化映射。我想我可以实现类似于编码器的 json
用法的东西,但这应该是一个常见的用例吗?
其他方法(例如 dataclasses(builtin)
+ 库(例如 dataclasses_jsonschema
)为 json-ready dict
提供了这种~序列化,但同样,希望使用 pydantic 进行更强大的输入验证,同时保持事物对称。
解决方法
当前版本的 pydantic
不支持直接创建 jsonable dict
。但是您可以使用以下技巧:
class Model(BaseModel):
the_id: UUID = Field(default_factory=uuid4)
print(json.loads(Model().json()))
{'the_id': '4c94e7bc-78fe-48ea-8c3b-83c180437774'}
或者更有效地通过orjson
orjson.loads(Model().json())
,
似乎已提出此功能,并且(可能)受到 pydantic 的作者塞缪尔·科尔文 (samuel colvin) 的青睐,如 https://github.com/samuelcolvin/pydantic/issues/951#issuecomment-552463606
建议在 simplify
中添加一个 Model.dict()
参数以输出 jsonalbe 数据。
此代码在生产 api 层中运行,并且已被使用,因此我们无法使用建议的单行解决方法(仅执行完整序列化 (.json()
) + 完整反序列化)。我们实现了一个自定义函数来执行此操作,对 .dict()
的结果进行降序并将类型转换为 jsonable - 希望上述建议的功能将来添加到 pydantic。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。