You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将JSON转换为Python对象?含复杂结构转换及后续DB数据校验需求

复杂JSON转Python对象及数据校验方案

你提供的JSON为Avro格式的结构化数据定义,以下是两种适配不同场景的实现方案:

方案1:无依赖基础转换

适合仅需要读取JSON属性、不需要额外校验的场景,直接用Python内置模块即可实现:

  • 第一步:先将JSON解析为Python字典
import json

# 从文件读取JSON,也可以直接用json.loads()解析JSON字符串
with open("schema.json", "r", encoding="utf-8") as f:
    schema_dict = json.load(f)

# 直接通过字典方式访问属性,例如 schema_dict["fields"][0]["name"]
  • 第二步(可选):转成支持.访问的简易对象
    如果不想用字典的方括号取值,可以通过递归转换为属性访问对象:
from types import SimpleNamespace

def dict_to_object(d: dict):
    if isinstance(d, dict):
        return SimpleNamespace(**{k: dict_to_object(v) for k, v in d.items()})
    elif isinstance(d, list):
        return [dict_to_object(item) for item in d]
    else:
        return d

schema_obj = dict_to_object(schema_dict)
# 之后可以直接用 . 访问属性,例如 schema_obj.namespace、schema_obj.fields[0].type

方案2:结构化类转换(适配后续DB数据校验)

如果需要做数据校验、字段类型自动转换,推荐用Pydantic实现结构化对象转换,自动校验字段类型、处理自定义逻辑(比如你示例中的日期、时间戳逻辑类型转换):

  • 首先根据JSON中定义的字段规则,编写对应的Pydantic模型:
from typing import Optional
from pydantic import BaseModel, field_validator
from datetime import date, datetime

class BloodDonor(BaseModel):
    id: int
    donor_number: str
    birth_date: date
    height: Optional[int] = None
    applicant_ts: Optional[datetime] = None
    arm_preference_ind: Optional[str] = None
    abo_ind: Optional[str] = None
    vein_grading_ind: Optional[str] = None

    # 自动转换int类型的日期(Avro默认date为1970年1月1日起的天数)
    @field_validator("birth_date", mode="before")
    def int_to_date(cls, value):
        if isinstance(value, int):
            return date.fromordinal(date(1970, 1, 1).toordinal() + value)
        return value

    # 自动转换毫秒级时间戳为Python datetime对象
    @field_validator("applicant_ts", mode="before")
    def long_to_datetime(cls, value):
        if isinstance(value, int):
            return datetime.fromtimestamp(value / 1000)
        return value
  • 用法示例:
    不管是从JSON读取的业务数据还是从数据库查询出来的数据,都可以直接传入模型初始化,自动完成校验和类型转换:
# 示例业务数据
raw_data = {
    "id": 1001,
    "donor_number": "DN202405001",
    "birth_date": 19723,
    "height": 178,
    "applicant_ts": 1717228800000,
    "arm_preference_ind": "RIGHT",
    "abo_ind": "O+",
    "vein_grading_ind": "GRADE_1"
}

# 初始化自动校验,字段不匹配会直接抛出明确的错误信息
donor_obj = BloodDonor(**raw_data)

# 校验完成后可以直接用属性访问,和DB查询结果直接对比即可,无需手动转格式
print(donor_obj.birth_date) # 输出为date类型的2023-12-25

内容的提问来源于stack exchange,提问作者Suresh S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.15 17:45:04