【问题标题】:How to define Pydantic Class for nested dictionary如何为嵌套字典定义 Pydantic 类
【发布时间】:2021-11-11 16:11:49
【问题描述】:

我们如何为以下嵌套字典结构(以复杂的字符串作为键)定义 Pydantic 类类型:

{ "inputs" : {
        "simpleStringName": <Simple_DateTime_Value>
        "simpleStringName2": {
        "Complicated|String|Name|with|Pipe|Characters" : <Simple-Int-Value>,
        "Complicated|String|Name2|with|Pipe|Characters" : <Simple-Int-Value2>
        }
    }
}

Pydantic 需要强制执行整个结构。那只是这行不通:

class XYZ(BaseModel):
    inputs : Dict()

我想使用 Pydantic 和 fastAPI 强制请求输入格式。

【问题讨论】:

    标签: python fastapi pydantic


    【解决方案1】:

    这样的事情可能就是你所追求的

    import datetime
    from typing import Union, Dict
    from pydantic import BaseModel
    
    class XYZ(BaseModel):
        inputs: Dict[str, Union[datetime.datetime, Dict[str, int]]]
    
    >>> XYZ(**{
    ...     "inputs" : {
    ...         "simpleStringName": datetime.datetime.utcnow(),
    ...         "simpleStringName2": {
    ...             "Complicated|String|Name|with|Pipe|Characters" : 3,
    ...             "Complicated|String|Name2|with|Pipe|Characters" : 4
    ...         }
    ...     }
    ... })
    XYZ(inputs={'simpleStringName': datetime.datetime(2021, 11, 11, 16, 34, 21, 906156), 'simpleStringName2': {'Complicated|String|Name|with|Pipe|Characters': 3, 'Complicated|String|Name2|with|Pipe|Characters': 4}})
    

    如果你想显式定义字符串,你可以使用 Pydantic 的约束类型(这里 constr 带有正则表达式,但有很多选项可用)
    https://pydantic-docs.helpmanual.io/usage/types/#constrained-types

    class XYZ(pydantic.BaseModel):
        inputs: Dict[
            pydantic.constr(regex="^[a-zA-Z\d]+$"),
            Union[
                datetime.datetime,
                Dict[
                    pydantic.constr(regex="^[a-zA-Z\d\|]+$"),
                    int
                ]
            ]
        ]
    

    【讨论】:

    • 可以不用pydantic.constr(regex="^[a-zA-Z\d]+$")直接提string_name吗?我想regex="fully_qualified_string_name" 无论如何都能解决问题?
    • 我其实不确定;可能有一些更简洁的方法可以将您的字段命名为不可能的 Python 标识符(即使只是像 5 这样的不起眼的 int 也是有问题的),但这并不是很明显 - Pydantic 对我来说有点新,我会诚实地尝试禁止字段名称它不能是 Python 标识符,也不能期望复杂数据被 base64 编码或完全抛弃 JSON 以获得一些灵活的二进制格式.. 是的!如果您知道确切的字段名称,则可以编写一个显式的正则表达式(您也可以使用re.escape(my_str) 在生成它时自动转义控制字符,如管道标记!)
    • 再详细一点,如果您确定字符串是什么,通常没有太多理由让它如此复杂(即"stringname2" 是否足够?)并打包任何有关它的额外信息到一些文档字符串 (pydantic-docs.helpmanual.io/usage/schema) .. 如果你不确定一个字段将被命名,你可以有一个明确的名称和数据字段,如{"name": "Complicated|String|Name2|with|Pipe|Characters", "data": &lt;Simple-Int-Value2&gt;},而不是尝试将它们配对时间
    猜你喜欢
    • 2022-01-15
    • 2020-11-25
    • 2021-02-02
    • 2021-11-26
    • 2021-06-08
    • 2019-09-17
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    相关资源
    最近更新 更多