我的API收到了以下字符串:

'{"data": 123, "inner_data": "{\\"color\\": \\"RED\\"}"}'

我的目标是构建一个能够验证外部和内部数据字段的pydantic模型. 因此,我构建了以下模型:

from pydantic import BaseModel

class InnerData(BaseModel):
    color: str

class Expected(BaseModel):
    data: int
    inner_data: InnerData

但当我运行以下命令时:

incoming_json_string = '{"data": 123, "inner_data": "{\\"color\\": \\"RED\\"}"}'
expected = Expected.model_validate_json(incoming_json_string)

我得到了:

Traceback (most recent call last):
  File ".../site-packages/pydantic/main.py", line 532, in model_validate_json
    return cls.__pydantic_validator__.validate_json(json_data, strict=strict, context=context)
pydantic_core._pydantic_core.ValidationError: 1 validation error for Expected
inner_data
  Input should be an object [type=model_type, input_value='{"color": "RED"}', input_type=str]
    For further information visit https://errors.pydantic.dev/2.5/v/model_type

回溯中的链接没有帮助,因为它告诉我数据是一个字符串,但应该是一个模型.但这就是我在做inner_data: InnerData米的时候想出来的.我该试试什么呢?

推荐答案

按照构建模型的方式,可以验证嵌套的JSON object,如下所示:

{
  "data": 123,
  "inner_data": {
    "color": "RED"
  }
}

皮丹蒂克将很高兴地将该JSON用于您的ExpectedInnerData类:

>>> incoming_json_string = '{"data": 123, "inner_data": {"color": "RED"}}'
>>> expected = Expected.model_validate_json(incoming_json_string)
>>> expected
Expected(data=123, inner_data=InnerData(color='RED'))

但是,如果希望inner_data接收JSON字符串而不是对象,则需要显式处理这种情况.你可以用BeforeValidator,就像这样:

from pydantic import BaseModel, BeforeValidator
from typing import Annotated

class InnerData(BaseModel):
    color: str

class Expected(BaseModel):
    data: int
    inner_data: Annotated[InnerData, BeforeValidator(InnerData.model_validate_json)]

incoming_json_string = '{"data": 123, "inner_data": "{\\"color\\": \\"RED\\"}"}'
expected = Expected.model_validate_json(incoming_json_string)

给定一个包含嵌套JSON字符串的JSON对象,如下所示:

{
  "data": 123,
  "inner_data": "{\"color\": \"RED\"}"
}

验证器将对JSON字符串进行解码,以使未序列化的结果与PYDANIC期望的InnerData匹配:

>>> incoming_json_string = '{"data": 123, "inner_data": "{\\"color\\": \\"RED\\"}"}'
>>> expected = Expected.model_validate_json(incoming_json_string)
>>> expected
Expected(data=123, inner_data=InnerData(color='RED'))

我对您试图解决的问题一无所知,但在大多数情况下,您实际上希望保持问题中的代码方式,并避免在JSON对象中嵌入JSON编码的数据.

Python-3.x相关问答推荐

这是重命名极地df列的最好方式吗?

估计列表中连续对的数量

Django中自动设置/更新字段

DataFrame列中如何迭代重复值?

如何将多输入数据加载器传递给单输入模型

如何将 WebDriver 传输到导入的测试?

如何在 histplot 中标记核密度估计

如何转置和 Pandas DataFrame 并命名新列?

DynamoDB - boto3 - batch_write_item:提供的关键元素与架构不匹配

如何将元组列表拆分为两个单独的列表?

使用正确的数据类型时,使用 Cerberus 验证 JSON 架构会引发错误

机器学习实验笔记本的工作区 url

如何在python中将列表转换为其他格式

如何并行化文件下载?

如何通过python打开文件

为什么包含类的名称不被识别为返回值函数注释?

如何在 Spyder 控制台中使用变量执行 Python 3.3 脚本?

if 语句中冒号的语法错误

如何在 Pandas 中的超 Big Data 框上创建数据透视表

交错4个相同长度的python列表