使用 pydantic 生成动态模型

问题描述

我正在尝试使用 Python 的 pydantic 库创建动态模型。我的输入数据是一个普通的 dict。但是,dict内容(读取:其键)可能会有所不同。
我想知道如何动态创建依赖于 pydantic 内容dict 模型?

我用两个不同的 dictinputs1inputs2)创建了一个玩具示例。让我们假设名为 dict 的嵌套 strategy 可能不同。根据 strategy/name,我提前知道 strategy 中将存在哪些字段。我需要基于 pydantic 创建 strategy/name 模型。

from pydantic import BaseModel

inputs1 = {
    "universe": {"name": "test_universe","ccy": "USD"},"price_src": "csv","strategy": {"name": "test_strat1"},}
inputs2 = {
    "universe": {"name": "test_universe","strategy": {"name": "test_strat2","periods": 10},}


class Universe(BaseModel):
    name: str
    ccy: str = "EUR"


strategy_name = "test_strat2"

if strategy_name == "test_strat1":
    inputs = inputs1

    class Strategy(BaseModel):
        name: str


elif strategy_name == "test_strat2":
    inputs = inputs2

    class Strategy(BaseModel):
        name: str
        periods: int


class StaticModel(BaseModel):
    universe: Universe
    price_src: str = "csv"
    strategy: Strategy


static_model = StaticModel(**inputs)

如果 ``strategy_name == "test_strat1" 我的预期输出

universe=Universe(name='test_universe',ccy='USD') price_src='csv' strategy=Strategy(name='test_strat1')

如果 ``strategy_name == "test_strat2" 我的预期输出

universe=Universe(name='test_universe',ccy='USD') price_src='csv' strategy=Strategy(name='test_strat2',periods=10)

我正在考虑使用 pydanticcreate_model 函数。但是,我不明白如何动态定义 fields

解决方法

对于pydantic模型的动态创建,可以使用create_model。像这样:

from pydantic import create_model

d = {"strategy": {"name": "test_strat2","periods": 10}}

Strategy = create_model("Strategy",**d["strategy"])

print(Strategy.schema_json(indent=2))

输出:

{
  "title": "Strategy","type": "object","properties": {
    "name": {
      "title": "Name","default": "test_strat2","type": "string"
    },"periods": {
      "title": "Periods","default": 10,"type": "integer"
    }
  }
}