JSON模式 - 基于条件需要嵌套属性

发布于 2025-01-23 23:15:08 字数 2320 浏览 0 评论 0原文

我试图为此创建一个最小可行的示例。我要实现的内容如下:

  1. 如果JSON包含POST,则同时进行ab at attrs >
  2. 如果JSON包含补丁,则不需要它们。
  3. 使用datamodel-codegen基于此模式生成Pydantic Dataclasses。

我相信有一种方法可以通过执行以下操作来验证,但是我不能以这种方式进行验证。由于某种原因,使用的模型生成器不能正确地将数据级属性设置为必需/可选定义这样的方式。

"attrs": {
    "additionalProperties": false,
    "properties": {
        "a": {
            "$ref": "#/$defs/a"
        },
        "b": {
            "$ref": "#/$defs/b"
        }
    }
},
"create": {
    "attrs": {
        "$ref": "#/$defs/attrs",
        "required": ["a", "b"]
    }
}

导致

class A(BaseModel):
    __root__: str


class B(BaseModel):
    __root__: str


class Attrs(BaseModel):
    class Config:
        extra = Extra.forbid

    a: Optional[A] = None
    b: Optional[B] = None


class Create(BaseModel):
    attrs: Attrs


class Update(BaseModel):
    attrs: Optional[Attrs] = None


class Model(BaseModel):
    patch: Optional[Update] = None
    post: Optional[Create] = None

这实际上是不正确的,因为这意味着每个单个属性都是可选的。我认为这是因为在架构中的位置,我定义了必需的属性。

取而代之的是,我想看看是否有一种方法可以在JSON模式中定义attrs定义中所需的和可选属性。

这是我作为模板制作的架构。我尝试使用和然后使用然后使用条件,但我无法弄清楚。

{
    "properties": {
        "patch": {
            "$ref": "#/$defs/update"
        },
        "post": {
            "$ref": "#/$defs/create"
        }
    },
    "$defs": {
        "create": {
            "properties": {
                "attrs": {
                    "$ref": "#/$defs/attrs"
                }
            }
        },
        "update": {
            "properties": {
                "attrs": {
                    "$ref": "#/$defs/attrs"
                }
            }
        },
        "attrs": {
            "additionalProperties": false,
            "properties": {
                "a": {
                    "$ref": "#/$defs/a"
                },
                "b": {
                    "$ref": "#/$defs/b"
                }
            }
        },
        "a": {
            "type": "string"
        },
        "b": {
            "type": "string"
        }
    }
}

我如何基于条件来定义attrs的所需属性,因为最高属性包含postpatch

I tried to create a minimum viable example for this. What I want to achieve is the following:

  1. if json contains post, then make both a and b required in attrs
  2. if json contains patch then make neither of them required.
  3. Use datamodel-codegen to generate pydantic dataclasses based on this schema.

I believe that there is a way to validate by doing the following, however I can't do it this way. For some reason the model generator being used does not properly set the dataclass properties to required/optional when defined this way.

"attrs": {
    "additionalProperties": false,
    "properties": {
        "a": {
            "$ref": "#/$defs/a"
        },
        "b": {
            "$ref": "#/$defs/b"
        }
    }
},
"create": {
    "attrs": {
        "$ref": "#/$defs/attrs",
        "required": ["a", "b"]
    }
}

leads to

class A(BaseModel):
    __root__: str


class B(BaseModel):
    __root__: str


class Attrs(BaseModel):
    class Config:
        extra = Extra.forbid

    a: Optional[A] = None
    b: Optional[B] = None


class Create(BaseModel):
    attrs: Attrs


class Update(BaseModel):
    attrs: Optional[Attrs] = None


class Model(BaseModel):
    patch: Optional[Update] = None
    post: Optional[Create] = None

This is actually incorrect because it implies that each individual attribute is optional. I assume this is because of where in the schema I defined the required property.

Instead, I would like to see if there is a way to define the required and optional properties in the definition of attrs in the json schema.

This is the schema I made as a template as an example. I tried using if and then conditions but I couldn't figure it out.

{
    "properties": {
        "patch": {
            "$ref": "#/$defs/update"
        },
        "post": {
            "$ref": "#/$defs/create"
        }
    },
    "$defs": {
        "create": {
            "properties": {
                "attrs": {
                    "$ref": "#/$defs/attrs"
                }
            }
        },
        "update": {
            "properties": {
                "attrs": {
                    "$ref": "#/$defs/attrs"
                }
            }
        },
        "attrs": {
            "additionalProperties": false,
            "properties": {
                "a": {
                    "$ref": "#/$defs/a"
                },
                "b": {
                    "$ref": "#/$defs/b"
                }
            }
        },
        "a": {
            "type": "string"
        },
        "b": {
            "type": "string"
        }
    }
}

How can I define the required properties of attrs based on the conditional, that being that the top level property contains post or patch?

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文