1

背景:我有多个引用大型相同对象的 json 模式。这些对象被移动到一个子目录。在下面的示例中,出现了以下依赖项:

  1. main_schema => positive_integer
  2. main_schema => 日期
  3. 日期 => 正整数
  4. 日期 => 月份

jsonschema 库仅无法解析最后一个依赖项,处理所有其他依赖项都很好。

项目树

/
+-- code.py
+-- schemas /
|   +-- dependencies /
|   |   +-- date.json
|   |   +-- month.json
|   |   +-- positive_integer.json
|   +-- main_schema.json

代码.py:

从 jsonschema 导入验证导入 json

contact = \
{
    "name": "William Johns",
    "age": 25,
    "birthDate": { "month": "apr", "day": 15 }
}

def main():
    schema = json.load(open("schemas/main_schema.json"))
    validate(contact, schema)

if (__name__ == '__main__'):
    main()

JSON 模式

main_schema json

{
    "title": "MainSchema",

    "properties":
    {
        "name":      { "type": "string" },
        "age":       { "$ref": "file:schemas/dependencies/positive_integer.json" },
        "birthDate": { "$ref": "file:schemas/dependencies/date.json" }
    },
    "additionalProperties": false
}

日期.json

{
    "title": "date",
    "type": "object",

    "properties":
    {
        "month": { "$ref": "file:month.json" },
        "day":   { "$ref": "file:positive_integer.json" }
    },
    "additionalProperties": false
}

月.json:

{
    "title": "month",
    "type": "string",
    "enum": [ "jan", "feb", "mar", "apr" ]
}

正整数.json:

{
    "title": "positiveInteger",
    "type": "integer",
    "minimum": 1
}

问题

当我运行它时,程序失败并显示堆栈跟踪:

"C:\Program Files (x86)\Python\3.6.0\python.exe" D:/Code/python/test/json_schema_testing/validator.py
Traceback (most recent call last):
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 380, in resolve_from_url
    document = self.store[url]
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\_utils.py", line 23, in __getitem__
    return self.store[self.normalize(uri)]
KeyError: 'file:///schemas/dependencies/month.json'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Python\3.6.0\lib\urllib\request.py", line 1474, in open_local_file
    stats = os.stat(localfile)
FileNotFoundError: [WinError 3] Системе не удается найти указанный путь: '\\schemas\\dependencies\\month.json'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 383, in resolve_from_url
    document = self.resolve_remote(url)
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 474, in resolve_remote
    result = json.loads(urlopen(uri).read().decode("utf-8"))
  File "C:\Program Files (x86)\Python\3.6.0\lib\urllib\request.py", line 223, in urlopen
    return opener.open(url, data, timeout)
  File "C:\Program Files (x86)\Python\3.6.0\lib\urllib\request.py", line 526, in open
    response = self._open(req, data)
  File "C:\Program Files (x86)\Python\3.6.0\lib\urllib\request.py", line 544, in _open
    '_open', req)
  File "C:\Program Files (x86)\Python\3.6.0\lib\urllib\request.py", line 504, in _call_chain
    result = func(*args)
  File "C:\Program Files (x86)\Python\3.6.0\lib\urllib\request.py", line 1452, in file_open
    return self.open_local_file(req)
  File "C:\Program Files (x86)\Python\3.6.0\lib\urllib\request.py", line 1492, in open_local_file
    raise URLError(exp)
urllib.error.URLError: <urlopen error [WinError 3] Системе не удается найти указанный путь: '\\schemas\\dependencies\\month.json'>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "D:/Code/python/test/json_schema_testing/validator.py", line 16, in <module>
    main()
  File "D:/Code/python/test/json_schema_testing/validator.py", line 13, in main
    validate(contact, schema)
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 541, in validate
    cls(schema, *args, **kwargs).validate(instance)
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 129, in validate
    for error in self.iter_errors(*args, **kwargs):
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 105, in iter_errors
    for error in errors:
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\_validators.py", line 304, in properties_draft4
    schema_path=property,
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 121, in descend
    for error in self.iter_errors(instance, schema):
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 105, in iter_errors
    for error in errors:
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\_validators.py", line 216, in ref
    for error in validator.descend(instance, resolved):
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 121, in descend
    for error in self.iter_errors(instance, schema):
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 105, in iter_errors
    for error in errors:
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\_validators.py", line 304, in properties_draft4
    schema_path=property,
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 121, in descend
    for error in self.iter_errors(instance, schema):
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 105, in iter_errors
    for error in errors:
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\_validators.py", line 212, in ref
    scope, resolved = validator.resolver.resolve(ref)
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 375, in resolve
    return url, self._remote_cache(url)
  File "C:\Program Files (x86)\Python\3.6.0\lib\site-packages\jsonschema\validators.py", line 385, in resolve_from_url
    raise RefResolutionError(exc)
jsonschema.exceptions.RefResolutionError: <urlopen error [WinError 3] Системе не удается найти указанный путь: '\\schemas\\dependencies\\month.json'>
(eng: System could not find such file: ...)

Process finished with exit code 1

正如我所调查的,“孙子”依赖关系只有在更早预加载的情况下才能得到解决。因此,如果删除“日期 => 月份”依赖项,或者从 rool 级别强制“预加载”它,一切都会正常工作。

解决方法

将 main_schema.json 修改为如下所示:

{
    "title": "MainSchema",

    "not":
    {
        "comment": "This is preload of 'grandchild' dependencies. It is required due to the jsonschema lib issues.",
        "anyOf":
        [
            { "$ref": "file:schemas/dependencies/month.json" },
            { "$ref": "file:schemas/dependencies/date.json" },
            { "$ref": "file:schemas/dependencies/positive_integer.json" }
        ]
    },


    "properties":
    {
        "name":      { "type": "string" },
        "age":       { "$ref": "file:schemas/dependencies/positive_integer.json" },
        "birthDate": { "$ref": "file:schemas/dependencies/date.json" }
    },
    "additionalProperties": false
}

如果这样做,验证将成功。但是,我真的不喜欢这种解决方法。如果您有任何解决方法的想法,请告诉我。

系统信息:

  • Windows 7的
  • Python 3.6.0
  • jsonschema 2.6.0
4

0 回答 0