jsonschema验证无法解析“孙子”本地文件引用

时间:2018-04-14 20:01:01

标签: python python-3.x jsonschema python-jsonschema

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

  1. main_schema => positive_integer
  2. main_schema =>日期
  3. date => positive_integer
  4. date =>月
  5. jsonschema库无法仅解析最后一个依赖项,处理所有其他依赖项。

    项目树

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

    code.py:

    来自jsonschema import validate     导入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
    }
    

    date.json

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

    month.json:

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

    positive_integer.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
    

    正如我调查的那样,“孙子”依赖关系只有在之前预先加载时才能解析。 因此,如果删除“date =&gt; month”依赖关系,或强制从preol级别“预加载”它,一切都会正常工作。

    解决方法

    将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

0 个答案:

没有答案