Вопрос или проблема
У меня есть базовая схема и расширенная схема ниже
./resources/json-schemas/simple-person.schema
{
"$id": "http://example.com/json-schemas/simple-person.schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Простой человек",
"type": "object",
"people": {
"items": {
"properties": {
"name": {
"type": "string",
"description": "Имя человека."
},
"age": {
"type": "integer",
"description": "Возраст человека."
}
},
"required": [
"name",
"age"
]
}
}
}
./extended-person.schema
{
"$id": "http://example.com/extended-person.schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Расширенный человек",
"type": "object",
"allOf": [
{
"$ref": "http://example.com/json-schemas/simple-person.schema"
},
{
"people": {
"items": {
"properties": {
"height": {
"type": "number",
"description": "Рост человека в сантиметрах."
},
"required": [
"height"
]
}
}
}
}
]
}
У меня также есть экземпляр этого набора данных, который я хочу проверить.
./person-dataset.json
{
"people": [
{
"name": "Боб",
"age": 25,
"new value": "значение"
}
]
}
Я ожидал, что валидация будет неудачной, но она проходит с помощью кода ниже
from pathlib import Path
import json
from referencing import Registry, Resource
from referencing.exceptions import NoSuchResource
from jsonschema import Draft202012Validator
def retrieve_from_filesystem(uri: str):
SCHEMAS = Path("./resources/json-schemas/")
if uri.startswith("http://example.com/json-schemas/"):
path = SCHEMAS / Path(uri.removeprefix("http://example.com/json-schemas/"))
else:
raise NoSuchResource(ref=uri)
contents = json.loads(path.read_text())
return Resource.from_contents(contents)
registry = Registry(retrieve=retrieve_from_filesystem)
schema = json.load(Path("./extended-person.schema").open())
instance = json.load(Path("./person-dataset.json").open())
validator = Draft202012Validator(schema, registry=registry)
validator.validate(instance)
Я ожидал, что это провалится по двум причинам
- в набор данных не включено свойство “height”
- в набор данных включено новое свойство “new value”, которое не указано в.schemas
Как мне это исправить, чтобы наборы данных, подобные этому, проваливались?
Ответ или решение
Для решения вашей проблемы с валидацией JSON-данных на основе расширенной схемы, необходимо внести несколько изменений в вашу схему и, возможно, в код, чтобы гарантировать, что экземпляры данных не проходят валидацию, если они содержат свойства, которые не предусмотрены схемой.
1. Исправление схемы
Сначала вам нужно убедиться, что в вашей расширенной схеме extended-person.schema
правильно определены все необходимые свойства. В частности, вам нужно добавить свойства required
на уровень объектов, содержащих свойство people
, чтобы указать, что наличие свойства height
обязательно.
{
"$id": "http://example.com/extended-person.schema",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Extended Person",
"type": "object",
"allOf": [
{
"$ref": "http://example.com/json-schemas/simple-person.schema"
},
{
"type": "object",
"properties": {
"people": {
"type": "array",
"items": {
"type": "object",
"properties": {
"height": {
"type": "number",
"description": "The person's height in centimeters."
}
},
"required": ["height"]
}
}
},
"required": ["people"]
}
]
}
2. Изменение логики валидации
В вашей текущей реализации валидации JSON-данных:
validator = Draft202012Validator(schema, registry=registry)
validator.validate(instance)
Данная инструкция не генерирует исключения, если данные не соответствуют требованиям вашей схемы. Для того чтобы отлавливать ошибки валидации, вы можете использовать блок try...except
и функцию validator.iter_errors(instance)
для корректного отображения ошибок валидации.
Вот пример кода с измененной логикой обработки ошибок:
try:
for error in validator.iter_errors(instance):
print(error.message)
print("Validation passed.")
except Exception as e:
print(f"Validation failed: {e}")
3. Ожидаемое поведение
После внесения вышеописанных изменений, ожидаемое поведение программы будет следующим:
- Валидация должна не проходить, если в данных отсутствует свойство
height
. - Валидация должна также не проходить, если в данных содержатся дополнительные свойства, которые не предусмотрены схемой, такие как
new value
.
4. Заключение
С учетом вышеизложенного, теперь схема и код должны корректно обрабатывать случай, когда JSON-данные не соответствуют ожиданиям. Проверьте эти изменения и, надеюсь, это решит вашу проблему с валидацией. Если у вас возникнут дополнительные вопросы, не стесняйтесь задавать их.