Pydantic 如何创建具有必填字段和动态字段的模型?

Pydantic how to create a model with required fields and dynamic fields?

我有动态 json 喜欢:

{
  "ts": 1111111,  // this field is required
  ...             // others are dynamic
}

除了 ts 之外,这些字段都是动态的。例如:

{"ts":111,"f1":"aa","f2":"bb"}
{"ts":222,"f3":"cc","f4":"dd"}

如何使用 Pydantic 声明此模型?

class JsonData(BaseModel):
    ts: int
    ...  # and then?

相当于打字稿:

interface JsonData {
  ts: number;
  [key: string]: any;
}

谢谢。

没有类型验证

如果类型验证无关紧要,那么您可以使用 extra option allow:

'allow' will assign the attributes to the model.

class JsonData(BaseModel):
    ts: int

    class Config:
        extra = "allow"

这将给出:

data = JsonData.parse_raw("""
{
   "ts": 222,
   "f3": "cc",
   "f4": "dd"
}
""")
repr(data)
# "JsonData(ts=222, f4='dd', f3='cc')"

并且可以通过以下方式访问这些字段:

print(data.f3)
# cc

有类型验证

但是,如果您可以更改请求正文以包含一个包含“动态字段”的对象,如下所示:

{
  "ts": 111,
  "fields": {
    "f1": "aa",
    "f2": "bb"
  }
}

{
  "ts": 222,
  "fields": {
    "f3": "cc",
    "f4": "dd"
  }
}

您可以使用像这样的 Pydantic 模型:

from pydantic import BaseModel

class JsonData(BaseModel):
    ts: int
    fields: dict[str, str] = {}

这样,可以处理任意数量的字段,同时验证字段类型,例如:

# No "extra" fields; yields an empty dict:
data = JsonData.parse_raw("""
{
  "ts": "222"
}
""")
repr(data)
# "JsonData(ts=222, fields={})"
# One extra field:
data = JsonData.parse_raw("""
{
  "ts": 111,
  "fields": {
    "f1": "aa"
  }
}
""")
repr(data)
# "JsonData(ts=111, fields={'f1': 'aa'})"
# Several extra fields:
data = JsonData.parse_raw("""
{
  "ts": 222,
  "fields": {
    "f2": "bb",
    "f3": "cc",
    "f4": "dd"
  }
}
""")
repr(data)
# "JsonData(ts=222, fields={'f2': 'bb', 'f3': 'cc', 'f4': 'dd'})"

字段可以这样访问:

print(data.fields["f2"])
# bb

在这种情况下,您可能还想将字段类型考虑为 StrictStr 而不是 str。使用 str 时,其他类型将被强制转换为字符串,例如当传入整数或浮点数时。StrictStr 不会发生这种情况。

另请参阅:this workaround