如何使用 pydantic 和 dict 数据类型创建动态模型
How to create dynamic models using pydantic and a dict data type
我正在尝试将 yml 文件加载到 dict
,使用 pyyaml
,加载过程会自动为我加载正确的类型,例如,包含以下内容的 yml 文件:
key1: test
key2: 100
将被加载到一个dict
的{"key1": "test", "key2":100}中,其中key1的值的类型是string
,key2的值的类型是 int
.
现在我想基于这个 dict
动态创建一个 class,基本上是一个 class,它有 dict
键作为字段和 dict
值如下所示:
class Test:
key1: str = "test"
key2: int = 100
我相信我可以使用 Pydantic
:
做类似下面的事情
Test = create_model('Test', key1=(str, "test"), key2=(int, 100))
但是,如此处所示,我必须手动告诉 create_model
用于创建此模型的键和类型。不知有没有away自动使用dict
中的items创建模型?
是的,例如,您可以递归调用 create_model
字典项,传递键和值类型,值本身可以成为默认值。
示例(未准备好生产):
from typing import Dict
from pydantic import create_model
test_dict = {'a': 12, 'nested': {'b': 'value', 'c': 1}}
def _make_model(v, name):
if type(v) is dict:
return create_model(name, **{k: _make_model(v, k) for k, v in v.items()}), ...
return type(v), v
def make_model(v: Dict, name: str):
return _make_model(v, name)[0]
model = make_model(test_dict, 'MyModel')
m = model.parse_obj(test_dict)
print(m)
print(model.schema_json(indent=2))
输出:
a=12 nested=nested(b='value', c=1)
{
"title": "MyModel",
"type": "object",
"properties": {
"a": {
"title": "A",
"default": 12,
"type": "integer"
},
"nested": {
"$ref": "#/definitions/nested"
}
},
"required": [
"nested"
],
"definitions": {
"nested": {
"title": "nested",
"type": "object",
"properties": {
"b": {
"title": "B",
"default": "value",
"type": "string"
},
"c": {
"title": "C",
"default": 1,
"type": "integer"
}
}
}
}
}
我正在尝试将 yml 文件加载到 dict
,使用 pyyaml
,加载过程会自动为我加载正确的类型,例如,包含以下内容的 yml 文件:
key1: test
key2: 100
将被加载到一个dict
的{"key1": "test", "key2":100}中,其中key1的值的类型是string
,key2的值的类型是 int
.
现在我想基于这个 dict
动态创建一个 class,基本上是一个 class,它有 dict
键作为字段和 dict
值如下所示:
class Test:
key1: str = "test"
key2: int = 100
我相信我可以使用 Pydantic
:
Test = create_model('Test', key1=(str, "test"), key2=(int, 100))
但是,如此处所示,我必须手动告诉 create_model
用于创建此模型的键和类型。不知有没有away自动使用dict
中的items创建模型?
是的,例如,您可以递归调用 create_model
字典项,传递键和值类型,值本身可以成为默认值。
示例(未准备好生产):
from typing import Dict
from pydantic import create_model
test_dict = {'a': 12, 'nested': {'b': 'value', 'c': 1}}
def _make_model(v, name):
if type(v) is dict:
return create_model(name, **{k: _make_model(v, k) for k, v in v.items()}), ...
return type(v), v
def make_model(v: Dict, name: str):
return _make_model(v, name)[0]
model = make_model(test_dict, 'MyModel')
m = model.parse_obj(test_dict)
print(m)
print(model.schema_json(indent=2))
输出:
a=12 nested=nested(b='value', c=1)
{
"title": "MyModel",
"type": "object",
"properties": {
"a": {
"title": "A",
"default": 12,
"type": "integer"
},
"nested": {
"$ref": "#/definitions/nested"
}
},
"required": [
"nested"
],
"definitions": {
"nested": {
"title": "nested",
"type": "object",
"properties": {
"b": {
"title": "B",
"default": "value",
"type": "string"
},
"c": {
"title": "C",
"default": 1,
"type": "integer"
}
}
}
}
}