背景:我有多个引用大型相同对象的 json 模式。这些对象被移动到一个子目录。在下面的示例中,出现了以下依赖项:
- main_schema => positive_integer
- main_schema => 日期
- 日期 => 正整数
- 日期 => 月份
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