gpt4 book ai didi

Python/Pydantic - 使用带有 json 对象的列表

转载 作者:行者123 更新时间:2023-12-01 00:32:30 28 4
gpt4 key购买 nike

我有一个使用 pydantic 接收 json 数据集的工作模型。模型数据集如下所示:

data = {'thing_number': 123, 
'thing_description': 'duck',
'thing_amount': 4.56}

我想做的是将 json 文件列表作为数据集并能够验证它们。最终该列表将转换为 pandas 中的记录以供进一步处理。我的目标是验证任意长的 json 条目列表,如下所示:

bigger_data = [{'thing_number': 123, 
'thing_description': 'duck',
'thing_amount': 4.56},
{'thing_number': 456,
'thing_description': 'cow',
'thing_amount': 7.89}]

我现在的基本设置如下。请注意,添加类 ItemList 是尝试使任意长度起作用的一部分。

from typing import List
from pydantic import BaseModel
from pydantic.schema import schema
import json

class Item(BaseModel):
thing_number: int
thing_description: str
thing_amount: float

class ItemList(BaseModel):
each_item: List[Item]

然后,基本代码将生成我认为我正在寻找的数组对象,该数组对象将采用 Item 对象。

item_schema = schema([ItemList])
print(json.dumps(item_schema, indent=2))

{
"definitions": {
"Item": {
"title": "Item",
"type": "object",
"properties": {
"thing_number": {
"title": "Thing_Number",
"type": "integer"
},
"thing_description": {
"title": "Thing_Description",
"type": "string"
},
"thing_amount": {
"title": "Thing_Amount",
"type": "number"
}
},
"required": [
"thing_number",
"thing_description",
"thing_amount"
]
},
"ItemList": {
"title": "ItemList",
"type": "object",
"properties": {
"each_item": {
"title": "Each_Item",
"type": "array",
"items": {
"$ref": "#/definitions/Item"
}
}
},
"required": [
"each_item"
]
}
}
}

该设置适用于正在传递的单个 json 项目:

item = Item(**data)                                                      

print(item)

Item thing_number=123 thing_description='duck' thing_amount=4.56

但是当我尝试将单个项目传递到 ItemList 模型时,它会返回错误:

item_list = ItemList(**data)

---------------------------------------------------------------------------
ValidationError Traceback (most recent call last)
<ipython-input-94-48efd56e7b6c> in <module>
----> 1 item_list = ItemList(**data)

/opt/conda/lib/python3.7/site-packages/pydantic/main.cpython-37m-x86_64-linux-gnu.so in pydantic.main.BaseModel.__init__()

/opt/conda/lib/python3.7/site-packages/pydantic/main.cpython-37m-x86_64-linux-gnu.so in pydantic.main.validate_model()

ValidationError: 1 validation error for ItemList
each_item
field required (type=value_error.missing)

我还尝试将 bigger_data 传递到数组中,认为它需要作为列表启动。这也会返回一个错误 - - 虽然,我至少对字典错误有了更好的理解,但我不知道如何解决。

item_list2 = ItemList(**data_big)

---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-100-8fe9a5414bd6> in <module>
----> 1 item_list2 = ItemList(**data_big)

TypeError: MetaModel object argument after ** must be a mapping, not list

谢谢。

我尝试过的其他事情

我尝试过将数据传递到特定的键中,运气好一点(也许?)。

item_list2 = ItemList(each_item=data_big)

---------------------------------------------------------------------------
ValidationError Traceback (most recent call last)
<ipython-input-111-07e5c12bf8b4> in <module>
----> 1 item_list2 = ItemList(each_item=data_big)

/opt/conda/lib/python3.7/site-packages/pydantic/main.cpython-37m-x86_64-linux-gnu.so in pydantic.main.BaseModel.__init__()

/opt/conda/lib/python3.7/site-packages/pydantic/main.cpython-37m-x86_64-linux-gnu.so in pydantic.main.validate_model()

ValidationError: 6 validation errors for ItemList
each_item -> 0 -> thing_number
field required (type=value_error.missing)
each_item -> 0 -> thing_description
field required (type=value_error.missing)
each_item -> 0 -> thing_amount
field required (type=value_error.missing)
each_item -> 1 -> thing_number
field required (type=value_error.missing)
each_item -> 1 -> thing_description
field required (type=value_error.missing)
each_item -> 1 -> thing_amount
field required (type=value_error.missing)

最佳答案

为了避免 ItemList 中出现 "each_item",您可以使用 __root__ Pydantic 关键字:

from typing import List
from pydantic import BaseModel

class Item(BaseModel):
thing_number: int
thing_description: str
thing_amount: float

class ItemList(BaseModel):
__root__: List[Item] # ⯇-- __root__

构建item_list:

just_data = [
{"thing_number": 123, "thing_description": "duck", "thing_amount": 4.56},
{"thing_number": 456, "thing_description": "cow", "thing_amount": 7.89},
]
item_list = ItemList(__root__=just_data)

a_json_duck = {"thing_number": 123, "thing_description": "duck", "thing_amount": 4.56}
item_list.__root__.append(a_json_duck)

支持 Pydantic 的 Web 框架通常将此类 ItemList jsonify 为 JSON 数组,而无需中间 __root__ 关键字。

关于Python/Pydantic - 使用带有 json 对象的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58068001/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com