在 BaseModel 中传递 int 字符串

Passing string of int in BaseModel

我正在尝试通过使用 BaseModel 进行数据验证的 POST 方法构建一个 fastAPI。 我的(简化)输入数据是一个 JSON,看起来像:

{   
"name": "test",
"a": {
    "b": {
        "c": {
            "0": "Fl"
        },
        "400": {
            "0": 0
        }
    },
    "d": {
        "400": {
            "0": 56.3,
            "1": 78.3,
            "2": 96.1,
            "3": 101.58
            }
        }
    }
}

当我尝试创建我的 BaseModel 时,PyCharm 通知我将 400、str(400) 或“400”作为键是错误的。所以我会有一个 class 有点像:

class D_0123(BaseModel):
    0: float
    1: float
    2: float
    3: float

class BD(BaseModel):
    400: Dict[D_0123]

class Item(BaseModel):
    name: str
    a: Dict[BD]

PyCharm 给我一个错误:'An illegal target for a variable allocation'。 我知道 JSON 不能将 int 作为键,因为它们会自动转换为“int”。

所以我想知道我想做的事情是否可行?有解决方法吗?

谢谢大家的宝贵时间!

祝你有愉快的一天!

pydantic(以及 FastAPI)利用的 Python 语法是:

class SomeName:
   attribute_name: type

BaseModel superclass 可能有一个自定义元class(或自定义__init_subclass__ 方法)读取class 属性的名称及其相关类型。 attribute_name 必须 遵循 Python 的标识符语义,因此它必须以字母开头并以字母数字+下划线继续。

因此我认为通常¹您不能利用使用不可接受的键作为标识符的“自动”验证,您必须使用自己的代码验证字段内容。
或者你可以改变约定,任何由数字组成的键都以下划线开头,如果 pydantic 不忽略下划线前缀的 class 成员。

¹ 我说“通常”是因为您可以替换:

class D_0123(BaseModel):
    0: float
    1: float
    2: float
    3: float

与:

D_0123 = type('D_0123', (BaseModel,), {"0": None, "1": None, "2": None, "3": None})
D_0123.__annotations__ = {"0": float, "1": float, "2": float, "3": float}

但我非常怀疑它是否会像您期望的那样工作;这取决于 BaseModel 的定义以及子 class(即 D_0123)创建期间完成的处理量。

PS 另请参阅 FastAPI 文档中的 Bodies of arbitrary dicts