python - Pydantic 字典列表通过其键转换为单个字典

标签 python dictionary pydantic

我有以下 pydantic 基本模型:

from typing import Dict, List, Optional, Union
from pydantic import BaseModel

class WSMessage(BaseModel):
    action: str
    success: Optional[bool] = None
    sent_from: Optional[str] = None
    send_to: Optional[str] = None
    data: Optional[Union[str, Dict, List]] = None
    msg: Optional[Union[str, Dict, List]] = None
    reason: Optional[Union[str, Dict, List]] = None
    class Config:
        extra = "allow"

以及以下数据:

data = {
    'action': 'reply',
    'sent_from': 'master',
    'send_to': '192.168.0.100_UE4yWw69iSBEf67JhhWTpg==',
    'data': None,
    'success': True,
    'msg': [
        {'name': 'entry1_name', 'value': 'entry1_value'},
        {'name': 'entry2_name', 'value': 'entry2_value'}
    ],
    'reason': None,
    'to_action': 'get_system_properties',
    'completed': True,
}

但是,当我尝试将值加载到 pydantic 模型中时,data['msg'] 被转换为单个字典而不是字典列表。

>>> msg = WSMessage(**data)
>>> msg
WSMessage(
    action='reply',
    success=True,
    sent_from='jumphost',
    send_to='46.235.96.113_UE4yWw69iSBEf67JhhWTpg==',
    data=None,
    msg={'name': 'value'},
    reason=None,
    completed=True,
    to_action='get_system_properties'
)
>>> msg.msg
{'name': 'value'}

我做错了什么?我希望 msg 接受任何形式的数据。或者更具体地说,字符串、字典或列表。

如果我从模型中删除 'msg',它会正确地将其解析为字典列表。

最佳答案

您的代码几乎可以工作。首先,您应该使用 List[dict] 而不是 List,因为它更精确。其次,当您使用Union定义字段时,pydantic将按照并集的顺序进行匹配(第一个匹配的数据结构)。

编写代码时:

msg: Optional[Union[str, Dict, List[Dict]] = None

给定一个字典列表,pydantic 将尝试将您的值强制转换为 dict(在尝试 dict 列表之前) - 因为列表中的第一个对象是一个字典,它可以成功地强制它并完成。

如果切换联合的顺序:

msg: Optional[Union[str, List[Dict], Dict]] = None

Pydantic 现在将首先检查该值是否是字典列表,然后再解析以匹配字典。现在应该可以了。

相关:受歧视的工会是 pydantic 中经常争论的话题:

关于python - Pydantic 字典列表通过其键转换为单个字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75399828/

相关文章:

Python 3 尝试排除问题

python - 按 x、y 和多个 z 存储点

python - pydantic 模块仅在 init 中检查变量

python - 如何设置 Pydantic 字段上的所有枚举值?

python - urllib/urllib2 返回的错误码和实际页面

python - 如何进行多个查询?

python - 如何抵消 Pandas Pearson 与日期时间索引的相关性

Python:使用 FOR 循环插入字典

c++ - 重建三角形网格中的所有边

python - 检查 JSON 字符串是否是有效的 Pydantic 模式