pydantic 转换为 jsonable dict(不是完整的 json 字符串)

Posted

技术标签:

【中文标题】pydantic 转换为 jsonable dict(不是完整的 json 字符串)【英文标题】:pydantic convert to jsonable dict (not full json string) 【发布时间】:2021-04-13 18:00:37 【问题描述】:

我想使用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 具有所有映射,但我在 pydantic/main.py 中找不到标准 json ~递归编码器 (json.dumps( ... default=pydantic_encoder)) 之外的任何序列化用法。但我更愿意为 validate raw->obj (pydantic 擅长于此)和 obj->raw(dict) 保留一个库,这样我就不必管理多个序列化映射。我想我可以实现类似于编码器的json 用法的东西,但这应该是一个常见的用例?

dataclasses(builtin) 等其他方法 + dataclasses_jsonschema 等库为json-ready dict 提供了这种〜序列化,但同样希望使用 pydantic 进行更强大的输入验证,同时保持对称。

【问题讨论】:

在***.com/a/69740271/317460 上查看我的回复 - 这是一个 Pydantic 自定义类型,特定于 UUID 的示例 【参考方案1】:

pydantic的当前版本不支持直接创建jsonabledict。但是您可以使用以下技巧:

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())

【讨论】:

看起来@samuelcolvin 正在考虑将simplify arg 添加到dict() 或类似的github.com/samuelcolvin/pydantic/issues/…;由于这是pydantic作者提出的,我希望有进展,但还没有完成对github的挖掘 感谢您的回答,但在生产环境中不能考虑为序列化/反序列化的完整往返付费。目前我们已经实现了一个自定义解决方法。【参考方案2】:

如果您已经在使用 fastapi 中的 jsonable_encoder 方法,则另一种选择是:https://fastapi.tiangolo.com/tutorial/encoder/

代码看起来很独立,因此如果许可证允许,您可以复制粘贴它。

【讨论】:

【参考方案3】:

这个功能似乎已经被提出,并且(可能)受到 pydantic 的作者 samuel colvin 的青睐,https://github.com/samuelcolvin/pydantic/issues/951#issuecomment-552463606

它建议在Model.dict() 中添加一个simplify 参数以输出jsonalbe 数据。

此代码在生产 api 层中运行,并且已经过大,因此我们无法使用建议的单行解决方法(只需执行完全序列化 (.json()) + 完全反序列化)。我们实现了一个自定义函数来执行此操作,将.dict() 的结果降序并将类型转换为 jsonable - 希望上述提议的功能将来会添加到 pydantic。

【讨论】:

自此登陆:pydantic-docs.helpmanual.io/usage/exporting_models/#modeldict

以上是关于pydantic 转换为 jsonable dict(不是完整的 json 字符串)的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Pydantic BaseModels 列表转换为 Pandas Dataframe

如何使用 Pydantic 解析模型列表

pydantic.BaseModel:父类的类方法

在 pydantic 模型中包含非验证方法是不好的做法吗?

如何在 pydantic 模型中解析 ObjectId?

json模块pickle模块(序列化)shelve模块