You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Cerberus中为递归数据结构(如树)建模Schema并验证?

Cerberus v1.3.5 递归树形结构验证的正确Schema建模方式

需求

使用Python Cerberus(v1.3.5)验证递归树形数据结构:节点要么是包含value整数字段的叶子节点,要么是包含任意深度子节点的分支节点。


尝试过程

尝试#1

尝试通过schema_registry定义递归结构:

from cerberus import Validator, schema_registry
schema_registry.add("leaf", {"value": {"type": "integer", "required": True}})
schema_registry.add("tree", {"type": "dict", "anyof_schema": ["leaf", "tree"]})
v = Validator(schema = {"root": {"type": "dict", "schema": "tree"}})

错误信息:

cerberus.schema.SchemaError: {'root': [{
    'schema': [
        'no definitions validate', {
            'anyof definition 0': [{
                'anyof_schema': ['must be of dict type'], 
                'type': ['null value not allowed'],
            }],
            'anyof definition 1': [
                'Rules set definition tree not found.'
            ],
        },
    ]},
]}

尝试#2

根据错误提示改用rules_set_registry定义:

from cerberus import Validator, schema_registry, rules_set_registry
schema_registry.add("leaf", {"value": {"type": "integer", "required": True}})
rules_set_registry.add("tree", {"type": "dict", "anyof_schema": ["leaf", "tree"]})
v = Validator(schema = {"root": {"type": "dict", "schema": "tree"}})

v.validate({"root": {"value": 1}})
v.errors
v.validate({"root": {"a": {"value": 1}}})
v.errors
v.validate({"root": {"a": {"b": {"c": {"value": 1}}}}})
v.errors

输出结果:

False
{'root': ['must be of dict type']}

所有测试用例均验证失败。


预期行为

以下所有文档应通过验证:

v = Validator(schema = {"root": {"type": "dict", "schema": "tree"}})
assert v.validate({"root": {"value": 1}}), v.errors
assert v.validate({"root": {"a": {"value": 1}}}), v.errors
assert v.validate({"root": {"a": {"b": {"c": {"value": 1}}}}}), v.errors

正确实现方案

问题核心是递归规则的定义逻辑和引用方式错误,正确建模方式如下:

from cerberus import Validator, rules_set_registry, schema_registry

# 注册叶子节点Schema:必须包含整数类型的value字段
schema_registry.add("leaf", {"value": {"type": "integer", "required": True}})

# 注册树形递归规则集:节点二选一
rules_set_registry.add(
    "tree",
    {
        "anyof": [
            # 情况1:节点是叶子节点,匹配leaf Schema
            {"schema": "leaf"},
            # 情况2:节点是分支节点,所有子节点需符合tree规则
            {"valuesrules": {"rules_set": "tree"}}
        ]
    }
)

# 定义根节点验证规则:必须是符合tree规则的字典
validator = Validator({"root": {"type": "dict", "rules_set": "tree"}})

# 测试验证
assert validator.validate({"root": {"value": 1}}), validator.errors
assert validator.validate({"root": {"a": {"value": 1}}}), validator.errors
assert validator.validate({"root": {"a": {"b": {"c": {"value": 1}}}}}), validator.errors
print("所有测试用例验证通过")

关键说明

  1. 用rules_set实现递归:Cerberus规则集支持自引用,而schema_registry不支持直接递归引用自身。
  2. 分支节点用valuesrules:指定分支节点下所有子节点都必须符合tree规则,实现任意深度的递归验证。
  3. anyof区分节点类型:明确节点要么是叶子节点,要么是分支节点,覆盖所有合法情况。

内容的提问来源于stack exchange,提问作者Marc Carrère

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 16:24:56