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

迁移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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 04:02:43