Я пытаюсь проверить JSON в python, используя библиотеку jsonschema. Чего я хочу добиться, так это словаря с ключами, состоящими из ключей json, вызывающих проблемы и сообщения от валидатора в качестве значений.
С проверкой типа проблем нет, поскольку она возвращает путь к ключу json, который не проходит проверку. Моя проблема заключается в том, что ключ отсутствует, переменная пути в ValidationError пуста, и я не могу найти другое место, где указано, какой ключ json вызывает проблемы. Единственное место, в котором указывается, какой ключ json является проблемой, — это сообщение, но его разделение для извлечения этой информации больше похоже на обходной путь, чем на решение.
Код:
import jsonschema
schema = {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": {
"type": "string"
},
"email": {
"type": "string"
}
},
"required": ["name", "email"]
}
jsonToValidate = {
"name": 1234
}
validator = jsonschema.Draft202012Validator(schema)
errorsGenerator = validator.iter_errors(jsonToValidate)
errors = dict()
for err in errorsGenerator:
# errors.update({err.path[0], err.message})
print("path: ", err.path, " \n message: ", err.message)
Текущий выход:
path: deque(['name'])
message: 1234 is not of type 'string'
path: deque([])
message: 'email' is a required property
Ожидаемый результат: Словарь с ключом в виде ключа json, который вызывает проблемы, и сообщением в качестве значения. Для этого примера это будет выглядеть так:
{
"name": "1234 is not of type 'string'",
"email": 'email' is a required property
}
Итак, мой вопрос: возможно ли извлечь информацию о том, какой отсутствующий ключ json (требуемый схемой) вызвал ValidationError?






Судя по вашему примеру, это первое слово сообщения об ошибке, поэтому вы можете извлечь первое слово:
err.message.split(" ")[0]
И используйте это для создания своего словаря.
В репозитории jsonschema есть открытый отчет об ошибке именно по вашей проблеме, с кратким ответом, что в настоящее время нет стандартного способа получить отсутствующий необходимый ключ. Однако в комментарии к отчету упоминается обходной путь с помощью пользовательских валидаторов. Может быть, это был бы способ пойти и для вас.
Обновление: в качестве альтернативы вы можете использовать сочетание синтаксического анализа сообщений и использования доступных атрибутов: проанализируйте сообщение об ошибке для ключей required, как это предлагается в ответе пользователя user2704177; в противном случае используйте ValidationErrorpath, где это возможно. Итак, что-то вроде:
errors = dict()
for err in errorsGenerator:
if err.validator == "required":
# Parse first word of error message as key, strip surrounding quotes
errors[err.message.split(" ")[0].strip("'")] = err.message
else:
# Use last path element as key (empty string for empty path)
errors[err.path[-1] if err.path else ""] = err.message
print(errors)
# >>> {'name': "1234 is not of type 'string'", 'email': "'email' is a required property"}
Спасибо за указание на отчет об ошибке. Возможно, я попробую обходной путь, о котором вы упомянули, но пока это не так важно.
Ну да, но тогда мне нужно будет добавить код, чтобы проверить, относится ли ошибка к отсутствующему полю или несоответствующему типу, и обрабатывать их по-разному. Это немного усложняет код. Это конечно решение, но мне было интересно, есть ли что-то более элегантное/универсальное