迁移Python jsonschema至referencing库后验证失效问题求助
迁移jsonschema.RefResolver到referencing库的正确姿势
问题描述
我正尝试将应用从jsonschema.RefResolver迁移,测试时收到弃用提示:
jsonschema.RefResolver is deprecated
as of v4.18.0, in favor of the referencing library
现有旧代码可正确验证所有测试数据:
investigation_schema_path=os.path.join( BASE_DIR, "..", "resources", "schemas", base_schemas_dir, "core", "investigation_schema.json" ) with open(investigation_schema_path) as fp: investigation_schema = json.load(fp) # 以下是已弃用的jsonschema.RefResolver代码 resolver = RefResolver("file://" + investigation_schema_path, investigation_schema) validator = Draft4Validator(investigation_schema, resolver=resolver) validator.validate(json_to_validate)
按照官方文档替换为新代码后:
schema = Resource.from_contents(investigation_schema) registry = schema @ Registry() validator = Draft4Validator(schema, registry) validator.validate(json_to_validate)
原本能检测出错误的json_to_validate测试不再报错,返回{'errors': [], 'warnings': [], 'validation_finished': True},但正确JSON的测试仍可通过。求问如何正确使用新referencing库?
正确迁移方案
问题出在未正确配置注册表解析本地文件引用,且验证器参数传递格式有误。以下是修正后的完整步骤:
1. 正确加载带引用的本地Schema
直接用Resource.from_contents无法自动处理本地文件的相对引用,需先将本地路径转为标准URI再加载:
from referencing import Registry, Resource from referencing.jsonschema import DRAFT4 from jsonschema import Draft4Validator, exceptions import os import json from urllib.parse import urljoin investigation_schema_path = os.path.join( BASE_DIR, "..", "resources", "schemas", base_schemas_dir, "core", "investigation_schema.json" ) # 把本地绝对路径转为file协议URI schema_uri = urljoin("file:///", os.path.abspath(investigation_schema_path)) with open(investigation_schema_path) as fp: investigation_schema = json.load(fp)
2. 构建支持本地引用的注册表
需要自定义检索函数,让注册表能根据URI找到并加载对应的本地Schema文件:
def retrieve(uri): # 将URI转回本地文件路径(适配跨平台路径格式) file_path = uri.replace("file:///", "/") with open(file_path) as f: # 指定Schema遵循的Draft版本,这里用DRAFT4对应原代码的Draft4Validator return Resource.from_contents(json.load(f), default_specification=DRAFT4) # 初始化注册表并绑定检索函数 registry = Registry(retrieve=retrieve) # 加载主Schema并关联注册表 schema_resource = Resource.from_contents(investigation_schema, default_specification=DRAFT4) schema_resource @ registry
3. 正确初始化验证器并执行验证
验证器需传入原始Schema字典,同时传入配置好的注册表:
validator = Draft4Validator(investigation_schema, registry=registry) try: validator.validate(json_to_validate) # 验证通过逻辑 except exceptions.ValidationError as e: # 捕获验证错误,这里可以按原有逻辑收集错误信息 print(f"验证失败: {e.message}")
关键注意点
- 旧
RefResolver会自动处理本地相对引用,但新referencing库必须显式定义retrieve函数来加载外部Schema文件。 - URI与本地路径的转换要准确,用
os.path.abspath和urljoin处理跨平台路径差异。 - 验证器初始化时必须传入原始Schema字典,注册表作为参数传入,不能直接传入
schema对象。
内容的提问来源于stack exchange,提问作者knirirr
相关产品推荐
相关产品推荐

