新手如何在Python中利用JsonSchema校验接口返回数据格式

浅辰大大_3504

浅辰大大_3504

2026-10-21

928人浏览

原创

jsonschema.validate()仅抛出首个ValidationError且无路径信息,需用Draft7Validator.iter_errors()遍历全部错误并打印error.path和error.message才能准确定位嵌套字段问题。

新手如何在python中利用jsonschema校验接口返回数据格式

为什么直接用 jsonschema.validate() 会报错 ValidationError 却没提示具体哪条字段错了

因为默认校验器只抛异常,不主动输出路径和上下文。新手常卡在这一步,以为校验失败就是“格式不对”,其实可能是某个嵌套字段类型错、必填字段缺失,或字符串长度超限。

正确做法是捕获 ValidationError 并用 errors 迭代器逐条看:

from jsonschema import validate, ValidationError
from jsonschema.validators import Draft7Validator
from jsonschema.exceptions import SchemaError
<p>try:
validate(instance=response_data, schema=schema)
except ValidationError as e:</p><h1>从最深层错误开始打印(更准)</h1><pre class="brush:php;toolbar:false;">for error in sorted(Draft7Validator(schema).iter_errors(response_data), key=lambda e: e.path):
    print(f"{' -> '.join([str(p) for p in error.path])}: {error.message}")

  • 别用 validate() 简单包裹——它只抛第一个错误,而接口数据往往多处违规
  • 用 Draft7Validator(或 Draft202012Validator)的 iter_errors() 才能拿到全部问题
  • error.path 是 deque,要转成字符串才好读;error.message 是自然语言描述,比堆栈有用得多

写 schema 时,required 和 additionalProperties: false 必须配对用吗

不是必须,但强烈建议。单独写 required 只控制“该有的字段不能少”,不限制“不该有的字段不能多”;而 additionalProperties: false 才真正堵住字段污染。

比如后端加了个临时调试字段 debug_info,前端没适配,但校验没报错——这就是漏了 additionalProperties: false:

{
  "type": "object",
  "required": ["id", "name"],
  "properties": {
    "id": {"type": "integer"},
    "name": {"type": "string"}
  },
  "additionalProperties": false  // ← 关键!否则 {"id": 1, "name": "a", "debug_info": {}} 也能过
}
  • required 是字段存在性检查,additionalProperties 是字段白名单机制
  • 如果接口允许扩展字段(如某些 OpenAPI 场景),可设为 {"type": "object"},但别留空或写 true
  • 嵌套对象里也要各自声明 additionalProperties: false,父级设置不影响子级

遇到 datetime 字段校验失败,是因为 JSON Schema 本身不支持 date-time 吗

不是不支持,而是 Python 的 json.loads() 默认把 ISO 时间字符串当 str 处理,而 date-time 校验只认字符串格式,不负责类型转换。

chartjs-reporter
chartjs-reporter

此技能用于在用户需要将结构化数据(查询结果、CSV 摘要、JSON 记录或 Python 字典/列表)转换为独立的 HTML 页面时使用。

下载

所以只要返回值里的时间字段是标准 ISO 格式字符串(如 "2024-05-20T14:23:18Z"),date-time 就能校验成功:

{
  "type": "string",
  "format": "date-time"  // ← 这行有效,前提是 instance 是 str,不是 datetime 对象
}
  • 千万别在 schema 里写 "type": "string", "format": "date-time" 却传入 Python 的 datetime 实例——JSON 序列化后它就变成字符串了,但测试时若手动构造 dict 就容易传错类型
  • 如果后端返回的是毫秒时间戳(数字),就得用 "type": "integer" + "minimum",而不是 date-time
  • format 是语义提示,不是强制转换;校验器不会帮你把 "2024/05/20" 转成 ISO 格式

用 fastjsonschema 替换原生 jsonschema 能提速吗?要注意什么

能,编译后校验速度通常快 5–10 倍,尤其适合高频调用(如 mock server、自动化回归)。但它不兼容所有 draft 特性,且报错信息更简陋。

最常见坑是:它默认不校验 format 字段(包括 email、uri、date-time),必须显式开启:

import fastjsonschema
<h1>必须传 validate_formats=True,否则 format 校验形同虚设</h1><p>validator = fastjsonschema.compile(schema, validate_formats=True)</p><p>try:
validator(response_data)
except fastjsonschema.JsonSchemaException as e:
print(e.message)  # 注意:没有 path 层级,只有扁平错误消息
</p>
  • 如果你的 schema 重度依赖 format 校验(比如邮箱正则、URL 结构),又想用 fastjsonschema,务必加 validate_formats=True
  • 它不支持 $ref 远程引用(只支持本地 $ref),有模块化 schema 的项目要提前 resolve
  • 错误对象没有 path 和 context,定位深层字段问题比原生库吃力

复杂点在于:校验不是一次性的“对/错”判断,而是分层反馈+格式契约+运行时类型匹配。最容易被忽略的是——把校验当成类型断言用,却忘了 JSON 传输层根本没有 datetime 或 int64 这种类型,一切最终都是字符串或数字。

Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

python js json

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1771

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4604

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1729

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

27197

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3287

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

3287

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1203

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

596

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2563

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Uvicorn官方安装与入门手册
Uvicorn官方安装与入门手册

共0课时 | 0人学习

Python uv官方项目管理指南
Python uv官方项目管理指南

共0课时 | 0人学习

Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习