JSON Schema 本身不是一个 Python 库,而是一个规范,用于描述和验证 JSON 数据的结构,你可以把它想象成 JSON 数据的“蓝图”或“数据类型检查器”。

在 Python 中,我们通常使用一个叫做 jsonschema 的库来处理这个规范。
安装 jsonschema 库
你需要安装这个库,可以使用 pip:
pip install jsonschema
JSON Schema 的基本概念和常用关键字
在写 Python 代码之前,我们先要了解 JSON Schema 的基本构成,一个 Schema 本身也是一个 JSON 对象,它由一系列的关键字组成,用来描述你的数据应该是什么样的。
| 关键字 | 描述 | 示例 |
|---|---|---|
type |
定义数据的类型。 | "string", "number", "integer", "boolean", "array", "object", "null" |
properties |
(用于 object) 定义对象有哪些属性,以及每个属性的 Schema。 |
{ "name": { "type": "string" } } |
required |
(用于 object) 指定对象中哪些属性是必须的。 |
["name", "age"] |
items |
(用于 array) 定义数组中每个元素必须遵守的 Schema。 |
{ "type": "string" } |
minItems / maxItems |
(用于 array) 定义数组元素的最小/最大数量。 |
"minItems": 1 |
pattern |
(用于 string) 定义字符串必须匹配的正则表达式。 |
"pattern": "^\\d+$" (匹配纯数字) |
minimum / maximum |
(用于 number 或 integer) 定义数值的最小/最大值(不包含)。 |
"minimum": 0 |
minimum / maximum |
(用于 number 或 integer) 定义数值的最小/最大值(包含)。 |
"minimum": 0 |
enum |
定义值必须是给定的枚举值之一。 | "enum": ["red", "green", "blue"] |
$schema |
指定所使用的 JSON Schema 的版本,推荐使用最新版本。 | "$schema": "http://json-schema.org/draft-07/schema#" |
Python 中使用 jsonschema 的核心步骤
使用 jsonschema 库进行验证非常简单,主要分为三步:

- 定义你的 JSON Schema:一个 Python 字典,描述了有效数据的结构。
- 准备要验证的数据:一个 Python 字典,代表你想要检查的 JSON 数据。
- 调用
validate()函数:将数据和 Schema 传递给jsonschema.validate(),如果数据有效,函数正常返回;如果无效,则会抛出jsonschema.exceptions.ValidationError异常。
完整代码示例
下面我们通过一个具体的例子来演示。
场景:我们想要验证一个“用户”对象,一个有效的用户应该包含:
name: 字符串,且是必须的。age: 整数,必须在 18 到 120 之间(包含),且是必须的。email: 字符串,必须符合邮箱格式(简化版,使用正则),是必须的。is_active: 布尔值,可选。skills: 字符串数组,至少包含一项技能。
步骤 1 & 2: 定义 Schema 和待验证数据
# 1. 定义 JSON Schema (一个 Python 字典)
user_schema = {
"$schema": "http://json-schema.org/draft-07/schema#", # 指定 schema 版本: "User Schema",
"description": "A user object",
"type": "object",
"properties": {
"name": {
"description": "The user's full name",
"type": "string"
},
"age": {
"description": "The user's age in years",
"type": "integer",
"minimum": 18,
"maximum": 120
},
"email": {
"description": "The user's email address",
"type": "string",
"pattern": "^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$" # 简单的邮箱正则
},
"is_active": {
"description": "Whether the user account is active",
"type": "boolean"
},
"skills": {
"description": "A list of the user's skills",
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
}
},
"required": ["name", "age", "email", "skills"] # 指定必须的字段
}
# 2. 准备一些要验证的数据
# --- 这是一个有效的用户 ---
valid_user = {
"name": "John Doe",
"age": 30,
"email": "john.doe@example.com",
"is_active": True,
"skills": ["Python", "Django"]
}
# --- 这是一个无效的用户(缺少 age,skills 为空数组)---
invalid_user_1 = {
"name": "Jane Doe",
"email": "jane.doe@example.com",
"is_active": False,
"skills": [] # 违反了 minItems: 1
}
# --- 另一个无效的用户(age 超出范围,email 格式错误)---
invalid_user_2 = {
"name": "Peter Jones",
"age": 150, # 违反了 maximum: 120
"email": "peter.jones@", # 违反了 pattern
"skills": ["Java", "Spring"]
}
步骤 3: 执行验证
from jsonschema import validate
from jsonschema.exceptions import ValidationError
def validate_user(data, schema):
"""
验证用户数据,并打印结果。
"""
print(f"\n--- 正在验证数据: {data} ---")
try:
validate(instance=data, schema=schema)
print("✅ 验证通过!数据是有效的。")
except ValidationError as e:
print(f"❌ 验证失败!错误信息: {e.message}")
# 你可以打印更多关于错误的信息
print(f" 错误路径: {' -> '.join(map(str, e.path))}")
print(f" 无效值: {e.instance}")
# --- 执行验证 ---
print("--- 开始验证 ---")
validate_user(valid_user, user_schema)
validate_user(invalid_user_1, user_schema)
validate_user(invalid_user_2, user_schema)
运行结果
--- 开始验证 ---
--- 正在验证数据: {'name': 'John Doe', 'age': 30, 'email': 'john.doe@example.com', 'is_active': True, 'skills': ['Python', 'Django']} ---
✅ 验证通过!数据是有效的。
--- 正在验证数据: {'name': 'Jane Doe', 'email': 'jane.doe@example.com', 'is_active': False, 'skills': []} ---
❌ 验证失败!错误信息: [] is too short
错误路径: skills
无效值: []
--- 正在验证数据: {'name': 'Peter Jones', 'age': 150, 'email': 'peter.jones@', 'skills': ['Java', 'Spring']} ---
❌ 验证失败!错误信息: 'peter.jones@' does not match '^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
错误路径: email
无效值: peter.jones@
高级用法
a. 自定义错误消息
jsonschema 默认的错误消息很清晰,但如果你想自定义,可以使用 format 关键字(仅适用于字符串)或者通过捕获异常后修改程序逻辑来实现。
# 使用 format 提供更友好的描述
user_schema_with_format = {
# ... (其他部分保持不变)
"properties": {
"email": {
"type": "string",
"format": "email", # 'email' 是一个预定义的格式
"errorMessage": "请提供一个有效的电子邮箱地址。"
}
}
}
# 注意:直接使用 format: "email" 可能需要更高级的库(如 `jsonschema-with-format-nongpl`)
# 来完全支持,这里仅为演示,自定义错误通常在异常处理逻辑中完成。
b. 复杂 Schema: allOf, anyOf, oneOf, not
当需要组合多个条件时,这些关键字非常有用。

allOf: 必须同时满足所有子 Schema。anyOf: 必须满足至少一个子 Schema。oneOf: 必须且只能满足一个子 Schema。not: 不能满足给定的 Schema。
示例: 一个数字,它要么是 null,要么是一个大于 0 的整数。
import jsonschema
# 定义一个 Schema,要求值是 null 或者一个正整数
nullable_positive_integer_schema = {
"anyOf": [
{ "type": "null" },
{
"type": "integer",
"minimum": 1
}
]
}
# 测试数据
data1 = None
data2 = 42
data3 = -5
data4 = "hello"
print("\n--- 测试复杂 Schema ---")
try:
validate(instance=data1, schema=nullable_positive_integer_schema)
print(f"'{data1}' 是有效的。")
except ValidationError:
print(f"'{data1}' 是无效的。")
try:
validate(instance=data2, schema=nullable_positive_integer_schema)
print(f"'{data2}' 是有效的。")
except ValidationError:
print(f"'{data2}' 是无效的。")
try:
validate(instance=data3, schema=nullable_positive_integer_schema)
print(f"'{data3}' 是有效的。")
except ValidationError:
print(f"'{data3}' 是无效的。")
try:
validate(instance=data4, schema=nullable_positive_integer_schema)
print(f"'{data4}' 是有效的。")
except ValidationError:
print(f"'{data4}' 是无效的。")
c. 生成 JSON Schema (从 Python 类)
如果你使用像 Pydantic 这样的现代数据验证库,可以非常方便地从 Python 类生成 JSON Schema,这极大地简化了 Schema 的创建过程。
示例使用 Pydantic:
首先安装 Pydantic: pip install pydantic
from pydantic import BaseModel, EmailStr, constr, validator
from typing import List
class UserModel(BaseModel):
name: constr(min_length=1) # 至少一个字符的字符串
age: int
email: EmailStr
is_active: bool = True # 有默认值,所以不是必须的
skills: List[str]
# Pydantic 会自动生成符合 JSON Schema 的描述
# 你也可以添加自定义验证器
@validator('age')
def age_must_be_adult(cls, v):
if v < 18:
raise ValueError("用户必须年满18岁")
return v
# 从 Pydantic 模型生成 JSON Schema
user_schema_from_pydantic = UserModel.model_json_schema()
print("\n--- 由 Pydantic 生成的 JSON Schema ---")
import json
print(json.dumps(user_schema_from_pydantic, indent=2))
# 现在这个 schema 可以和 jsonschema 库一起使用
from jsonschema import validate
valid_pydantic_user = {"name": "Alice", "age": 25, "email": "alice@test.com", "skills": ["fast"]}
validate(instance=valid_pydantic_user, schema=user_schema_from_pydantic)
print("\n✅ Pydantic 生成的 Schema 验证通过!")
| 特性 | 描述 |
|---|---|
| 核心库 | jsonschema |
| 工作流程 | 定义 Schema -> 准备数据 -> 调用 validate() -> 处理异常 |
| 优点 | 标准化:JSON Schema 是一个业界标准,跨语言通用。 强大灵活:支持复杂的数据结构、嵌套、条件组合等。 自动化:可以集成到 CI/CD 流程中,确保 API 数据的正确性。 文档化:Schema 本身就是一份清晰的数据结构文档。 |
| 适用场景 | API 请求/响应数据验证、配置文件验证、数据清洗、确保数据一致性等。 |
希望这份详细的指南能帮助你掌握在 Python 中使用 JSON Schema!
