jsons数组的Pydantic模型

Posted

技术标签:

【中文标题】jsons数组的Pydantic模型【英文标题】:Pydantic model for array of jsons 【发布时间】:2020-08-13 06:24:07 【问题描述】:

我正在使用 FastAPI 编写 Web 服务。它又好又快。

FastAPI 使用 pydantic 模型来验证输入和输出数据,一切都很好,但是当我想为 json 数组声明嵌套模型时,如下所示:

[
   
      "name": "name1",
      "family": "family1"
   ,
   
      "name": "name2",
      "family": "family2"
   
]

我得到空响应。

我认为我的模型存在问题:

class Test(BaseModel):
    name: str
    family: str
    class Config:
        orm_mode = True

class Tests(BaseModel):
    List[Test]
    class Config:
        orm_mode = True

那么,我的问题是我应该如何为 json 数组编写模型?

【问题讨论】:

注意你有 "orm_mode = True" ,很可能你遇到了 ORM 问题,而不是你的 Pydantic 模型......不能说更多,因为你没有提供细节或你的ORM。 如果你正在发布 json 数据,fastapi 会尝试自动将其转换为 pydantic 模型。否则,您可以简单地将字段声明为数组,就像在测试中所做的那样。您是否尝试过删除“class Config: orm_mode = True”这段代码? 【参考方案1】:

更新(2020 年 9 月 26 日)

在 Python 3.9(尚未发布)中,您可以执行与以下 but with the built-in list generic type 相同的操作(始终在范围内),而不需要从 typing 导入大写的 List 类型,例如

@app.get("/tests", response_model=list[Test])

这里的问题是您正在尝试创建一个不需要它的 pydantic 模型。如果您想序列化/反序列化对象列表,只需将您的单一模型包装在 python 内置 typing 模块中的 List[] 中。无需尝试使用 pydantic BaseModel 创建对象的复数版本(如您所见,它无论如何都不起作用)。

话虽如此,最简单的方法是在需要Tests 列表的任何位置指定List[Test],例如

from typing import List

from fastapi import FastAPI
from pydantic import BaseModel


existing_tests = [
    
        "name": "name1",
        "family": "family1"
    ,
    
        "name": "name2",
        "family": "family2"
    
]


class Test(BaseModel):
    name: str
    family: str

    class Config:
        orm_mode = True


app = FastAPI()


@app.get("/tests", response_model=List[Test])
async def fetch_tests():
    return existing_tests


@app.post("/tests")
async def submit_tests(new_tests: List[Test]):
    print(new_tests)

当然,如果您发现自己反复(或仅)将 Test 指定为列表,您当然可以将其分配给一个变量,然后在需要时使用该变量,如下所示:

Tests = List[Test]

@app.get("/tests", response_model=Tests)
async def fetch_tests():
    return existing_tests

@app.post("/tests")
async def submit_tests(new_tests: Tests):
    print(new_tests)

我认为第一个选项在您的代码中可能稍微清晰一些,除非您多次指定 List[Test],否则为此目的使用变量可能不值得额外的间接层。

【讨论】:

这太棒了!没有看到太多关于如何使用 FastAPI 返回列表的好文档,这似乎是一个超级常见的用例。 这在 PyCharm 中给了我一个警告:Expected type 'Optional[type]', got 'GenericAlias' instead,但有效。 @A.Rabus 我也收到了警告。我们应该使用 typing List,还是 Python 3.9 list

以上是关于jsons数组的Pydantic模型的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 pydantic/fastapi 接受具有数组\单个项目的单个路由对象?

pydantic学习与使用-2.基本模型(BaseModel)使用

python - 如何在python中使用带有graphene-pydantic和graphene的子类中的pydantic模型?

pydantic学习与使用-7.字段顺序field-ordering

嵌套数组 JSON 的 Mongoose 模型

从 dict 生成 pydantic 模型