【问题标题】:Define a Pydantic (nested) model定义 Pydantic(嵌套)模型
【发布时间】:2022-01-15 00:01:33
【问题描述】:

如果我使用 GET(给定一个 id),我会得到如下 JSON:

{
    "data": {
        "id": "81",
        "ks": {
            "k1": 25,
            "k2": 5
        },
        "items": [
            {
                "id": 1,
                "name": "John",
                "surname": "Smith"
            },
            {
                "id": 2,
                "name": "Jane",
                "surname": "Doe"
            }
        ]
    },
    "server-time": "2021-12-09 14:18:40"
}

具体情况(如果 id 不存在):

{
    "data": {
        "id": -1,
        "ks": "",
        "items": []
    },
    "server-time": "2021-12-10 09:35:22"
}

我想创建一个 Pydantic 模型来管理这个数据结构(我的意思是正式定义这些对象)。 通过创建类(可能是嵌套的)来管理这种数据结构的最聪明的方法是什么?

【问题讨论】:

    标签: python json fastapi pydantic


    【解决方案1】:

    如果您不需要pydantic 提供的数据验证,您可以将数据类与dataclass-wizard 一起用于同一任务。它稍微容易一些,因为您不需要为诸如 server-time 之类的 lisp 大小写键定义映射。

    下面的简单示例:

    from __future__ import annotations
    
    from dataclasses import dataclass
    from datetime import datetime
    
    from dataclass_wizard import fromdict
    
    
    @dataclass
    class Something:
        data: Data
        # or simply:
        #   server_time: str
        server_time: datetime
    
    
    @dataclass
    class Data:
        id: int
        ks: dict[str, int]
        items: list[Person]
    
    
    @dataclass
    class Person:
        id: int
        name: str
        surname: str
    
    
    # note: data is defined in the OP above
    input_data = ...
    
    print(fromdict(Something, input_data))
    

    输出:

    Something(data=Data(id=81, ks={'k1': 25, 'k2': 5}, items=[Person(id=1, name='John', surname='Smith'), Person(id=2, name='Jane', surname='Doe')]), server_time=datetime.datetime(2021, 12, 9, 14, 18, 40))
    

    【讨论】:

    • 那么input_data 是否与我在问题中定义的第一个 JSON 完全匹配?要从对象 Something 获取 JSON,反之亦然,我们应该分别使用 asdict() 和 fromdict() 吗?
    • @LJG 是的,没错,input_data 应该与上面的 JSON 匹配。我注意到在这种情况下您的 JSON 数据可以简单地定义为 dict 对象。要获取 JSON 字符串,如果这是您的意图,您必须在 asdict 结果上调用 json.dumps,但是如果更方便,您可以从文档中提到的 JSONWizard mixin 类继承子类,然后可以只需使用to_json() 方法直接将实例转换为JSON 字符串。
    【解决方案2】:

    我看到你已经标记了 fastapi 和 pydantic,所以我建议你关注 official Tutorial 来了解 fastapi 的工作原理。你有一整部分解释了 pydantic 与 fastapi here 的用法。

    为了更准确地回答您的问题,pydantic 模型在the doc 中有很好的解释。

    简单的例子:

    from typing import List
    from pydantic import BaseModel
    
    class Data(BaseModel):
        id: int
        ks: str
        items: List[str]
    
    class Something(BaseModel):
        data: Data
        # you can replace it by a pydantic time type that fit your need
        server_time: str = Field(alias="server-time")
    

    【讨论】:

      【解决方案3】:
      from pydantic import BaseModel
      
      class User(BaseModel):
          id: int
          name = "Jane Doe"
      

      【讨论】:

      • 问题不是要求 任何 种 Pydantic 模型。该问题有一个特定的样本输入,需要嵌套 Pydantic 模型。
      猜你喜欢
      • 2021-09-06
      • 2022-07-28
      • 2022-11-26
      • 2021-05-12
      • 2021-11-13
      • 1970-01-01
      • 1970-01-01
      • 2021-03-04
      • 2021-09-06
      相关资源
      最近更新 更多