pydantic 转换为 jsonable 字典(不完整 json 字符串)
pydantic convert to jsonable dict (not full json string)
我想使用 pydantic
来处理 api 和数据存储之间的数据(双向),因为它很好地支持了我关心的几种非原生类型 json-可序列化。它具有比当前方法更好的 read/validation 支持,但我还需要创建 json-可序列化 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 进行更健壮的输入验证,同时保留东西对称。
当前版本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())
似乎已经提出了这个功能,并且(可能)受到 pydantic 的作者 samuel colvin 的青睐,因为 https://github.com/samuelcolvin/pydantic/issues/951#issuecomment-552463606
建议在Model.dict()
中添加一个simplify
参数来输出jsonalbe数据。
此代码在生产 api 层中运行,并且已被执行,因此我们无法使用建议的单行解决方法(只需执行完整序列化 (.json()
) + 完整反序列化).我们实现了一个自定义函数来执行此操作,降低 .dict()
的结果并将类型转换为 jsonable - 希望上面提议的功能在将来添加到 pydantic。
另一种方法是使用 fastapi
中的 jsonable_encoder
方法,如果您已经在使用该方法:https://fastapi.tiangolo.com/tutorial/encoder/
代码看起来很独立,所以如果许可证允许,您可以复制粘贴它。
我想使用 pydantic
来处理 api 和数据存储之间的数据(双向),因为它很好地支持了我关心的几种非原生类型 json-可序列化。它具有比当前方法更好的 read/validation 支持,但我还需要创建 json-可序列化 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 进行更健壮的输入验证,同时保留东西对称。
当前版本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())
似乎已经提出了这个功能,并且(可能)受到 pydantic 的作者 samuel colvin 的青睐,因为 https://github.com/samuelcolvin/pydantic/issues/951#issuecomment-552463606
建议在Model.dict()
中添加一个simplify
参数来输出jsonalbe数据。
此代码在生产 api 层中运行,并且已被执行,因此我们无法使用建议的单行解决方法(只需执行完整序列化 (.json()
) + 完整反序列化).我们实现了一个自定义函数来执行此操作,降低 .dict()
的结果并将类型转换为 jsonable - 希望上面提议的功能在将来添加到 pydantic。
另一种方法是使用 fastapi
中的 jsonable_encoder
方法,如果您已经在使用该方法:https://fastapi.tiangolo.com/tutorial/encoder/
代码看起来很独立,所以如果许可证允许,您可以复制粘贴它。