根据JSON模式设置默认值

发布于 2025-01-24 17:48:56 字数 1126 浏览 3 评论 0 原文

我正在使用 jsonschema python 中的软件包来验证我的jsons。我可以在 jsonschema 中设置默认。让我们假设以下架构:

from jsonschema import validate

schema = {
    "type": "object",
    "properties": {
        "key_1": {},
        "key_2": {
            "type": "string",
            "default": "do_not_overwrite_if_key_exists",
        },
        "key_3": {
            "type": "string",
            "default": "use_it_if_key_does_not_exist",
        },
    },
    "required": ["key_1"],
}

json_dict = {"key_1": "key_1_value", "key_2": "key_2_value"}

validate(json_dict, schema)

我的 JSON_DICT 是完全有效的。我有两个问题:

  1. 默认关键字真的如此“无用”(请参见下文)?这就是你得到的吗?

“默认”关键字没有效果,但是对于架构的读者来说,可以更轻松地识别默认行为。

  1. 我想拥有一种将我的 json_dict 转换为以下方法,根据默认关键字。你知道这样的包裹吗?
json_dict = {"key_1": "key_1_value", "key_2": "key_2_value", "key_3": "use_it_if_key_does_not_exist"}

谢谢!

I am using the jsonschema package in python to validate my JSONs. I can set default in jsonschema. Let us assume the following schema:

from jsonschema import validate

schema = {
    "type": "object",
    "properties": {
        "key_1": {},
        "key_2": {
            "type": "string",
            "default": "do_not_overwrite_if_key_exists",
        },
        "key_3": {
            "type": "string",
            "default": "use_it_if_key_does_not_exist",
        },
    },
    "required": ["key_1"],
}

json_dict = {"key_1": "key_1_value", "key_2": "key_2_value"}

validate(json_dict, schema)

My json_dict is perfectly valid. I have two questions:

  1. Is the default keyword really so "useless" as the documentation (see below) says? This is all you get?

The “default” keyword doesn’t have an effect, but is nice to include for readers of the schema to more easily recognize the default behavior.

  1. I would like to have a method that transforms my json_dict into the following according to the default keyword. Do you know of such a package?
json_dict = {"key_1": "key_1_value", "key_2": "key_2_value", "key_3": "use_it_if_key_does_not_exist"}

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦亿 2025-01-31 17:48:56

您可以使用 jsonschema_default 链接下面链接的软件包,以从JSON架构中生成默认的JSON对象。
https://pypi.org/project/jsonschema-default/

JSON_DICT 中的丢失密钥

”默认

import jsonschema_default as jd

default_obj = jd.create_from("./data_schema_example.json")

for key in default_obj.keys():
    if key not in json_dict:
        json_dict[key] = default_obj[key]  

You can use the jsonschema_default package linked below to generate a default JSON object from your JSON schema.
https://pypi.org/project/jsonschema-default/

Then you can use the default JSON object to fill in the missing key in your json_dict

Like so:

import jsonschema_default as jd

default_obj = jd.create_from("./data_schema_example.json")

for key in default_obj.keys():
    if key not in json_dict:
        json_dict[key] = default_obj[key]  
何时共饮酒 2025-01-31 17:48:56

默认关键字在此处记录: https://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.9.2.2

确实不是验证关键字作为注释。当通过模式评估生成时,决定如何使用此注释,这取决于单个应用程序。

The default keyword is documented here: https://json-schema.org/draft/2020-12/json-schema-validation.html#rfc.section.9.2

It is indeed not a validation keyword, and only acts as an annotation. It is up to individual applications to decide how to use this annotation when it is generated from schema evaluation.

2025-01-31 17:48:56

@AJack的JSonschema_default解决方案无法与部分填充的嵌套对象一起使用:键将存在,因此不会添加默认值。

假设我有此默认值:

{
  "foo": {
    "bar_1": "value_1",
    "bar_2": "value_2"
  },
  "other": "something"
}

并提供此JSON:

{
  "foo": {
    "bar_1": "value_1"
  }
}

然后仅将“其他” 添加使用默认值。 “ bar_2” 不会添加,因为“ foo” 存在。

带有递归的一种解决方案是搜索所有默认的嵌套结构以填充。这是我的解决方案的尝试:

def fill_default(json_dict, schema):
    for key in schema["properties"]:
        if "properties" in schema["properties"][key].keys(): # Recursion
            if key not in json_dict.keys():
                json_dict[key] = fill_default(dict(), schema["properties"][key])
            else:
                json_dict[key] = fill_default(json_dict[key], schema["properties"][key])
            if len(json_dict[key]) == 0: #No default found inside
                del json_dict[key]
        elif key not in json_dict.keys() and "default" in schema["properties"][key].keys():
            json_dict[key] = schema["properties"][key]["default"]
    return json_dict

json_dict = fill_default(json_dict, schema)

The jsonschema_default solution from @ajack wouldn't work with partially filled nested objects: The key would exist thus missing default values would not be added.

Say I have this default:

{
  "foo": {
    "bar_1": "value_1",
    "bar_2": "value_2"
  },
  "other": "something"
}

And provide this json:

{
  "foo": {
    "bar_1": "value_1"
  }
}

Then only "other" would be added with the default value. "bar_2" wouldn't be added because "foo" exists.

One solution with recursion is to search all nested structures with defaults to fill. This is my attempt of a solution:

def fill_default(json_dict, schema):
    for key in schema["properties"]:
        if "properties" in schema["properties"][key].keys(): # Recursion
            if key not in json_dict.keys():
                json_dict[key] = fill_default(dict(), schema["properties"][key])
            else:
                json_dict[key] = fill_default(json_dict[key], schema["properties"][key])
            if len(json_dict[key]) == 0: #No default found inside
                del json_dict[key]
        elif key not in json_dict.keys() and "default" in schema["properties"][key].keys():
            json_dict[key] = schema["properties"][key]["default"]
    return json_dict

json_dict = fill_default(json_dict, schema)
剧终人散尽 2025-01-31 17:48:56

您可以使用 fill_default 来自 /code> 用其模式填充现有实例中的所有缺失默认值:

pip install jsonschema-fill-default
from jsonschema_fill_default import fill_default

schema = {
    "type": "object",
    "properties": {
        "key_1": {},
        "key_2": {
            "type": "string",
            "default": "do_not_overwrite_if_key_exists",
        },
        "key_3": {
            "type": "string",
            "default": "use_it_if_key_does_not_exist",
        },
    },
    "required": ["key_1"],
}

json_dict = {"key_1": "key_1_value", "key_2": "key_2_value"}

fill_default(json_dict, schema)  # Mutates instance!
>>> json_dict

{"key_1": "key_1_value", "key_2": "key_2_value", "key_3": "use_it_if_key_does_not_exist"}

我创建了 jsonschema-fill-default ,tom-tbt的答案是 fill_default 的灵感来源。

填充是针对所有缺失和嵌套默认值的递归完成的。它与“ properties”的所有组合一起使用,“ allof” “ anyof” ,“ oneof” , “ depententsChemas” “ if-then(-else)” “ prefixItems” “关键字。

注意:

  • 该实例必须已经有效对其架构有效。
  • 架构本身必须是有效的草稿2020-12 json schema
  • 填充的实例未自动验证

参见示例在项目的github上,有关详细信息。

You can use fill_default from jsonschema-fill-default to fill all missing defaults in an existing instance with its schema:

pip install jsonschema-fill-default
from jsonschema_fill_default import fill_default

schema = {
    "type": "object",
    "properties": {
        "key_1": {},
        "key_2": {
            "type": "string",
            "default": "do_not_overwrite_if_key_exists",
        },
        "key_3": {
            "type": "string",
            "default": "use_it_if_key_does_not_exist",
        },
    },
    "required": ["key_1"],
}

json_dict = {"key_1": "key_1_value", "key_2": "key_2_value"}

fill_default(json_dict, schema)  # Mutates instance!
>>> json_dict

{"key_1": "key_1_value", "key_2": "key_2_value", "key_3": "use_it_if_key_does_not_exist"}

I created jsonschema-fill-default with Tom-tbt's answer as inspiration for fill_default.

The filling is done recursively for all missing and nested defaults. It works with all combinations of "properties", "allOf", "anyOf", "oneOf", "dependentSchemas", "if-then(-else)", "prefixItems", and "items" keywords.

Note:

  • The instance must already be valid to its schema.
  • The schema itself must be a valid Draft 2020-12 JSON Schema.
  • The filled instance is not automatically validated.

See Examples on the project's GitHub for details.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文