如何使用 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"
        }
      }
    }
  }
}