Python Cerberus 在模式中嵌入数字配置数据

Python Cerberus embed numeric config data in schema

我有一组文档和模式正在验证(令人震惊)。

这些文档是来自使用各种不同格式的各种不同客户端的 JSON 消息,因此为从这些客户端收到的每个 document/message 定义了一个架构。

我想使用 dispatcher(以函数调用作为值的字典)在根据匹配模式验证文档后帮助执行文档的 mapping/formatting。 一旦我知道一条消息对其有效的模式,我就可以通过调用必要的映射函数为我的各种消费者服务创建所需的消息负载。

为此,我的调度程序中需要一个键,该键唯一地映射到该模式的相应映射函数。密钥还需要用于标识模式,以便可以调用正确的映射函数。

我的问题是:有没有办法将数字 ID 之类的配置值嵌入到架构中?

我想采用这个模式:

schema = {
    "timestamp": {"type": "number"},
    "values": {
        "type": "list",
        "schema": {
            "type": "dict",
            "schema": {
                "id": {"required": True, "type": "string"},
                "v": {"required": True, "type": "number"},
                "q": {"type": "boolean"},
                "t": {"required": True, "type": "number"},
            },
        },
    },
}

然后像这样添加一个 schema_id

schema = {
    "schema_id": 1,
    "timestamp": {"type": "number"},
    "values": {
        "type": "list",
        "schema": {
            "type": "dict",
            "schema": {
                "id": {"required": True, "type": "string"},
                "v": {"required": True, "type": "number"},
                "q": {"type": "boolean"},
                "t": {"required": True, "type": "number"},
            },
        },
    },
}

因此,在成功验证后,message/document 之间的 link 通过 schema_id 到调度程序中生成的 mapping_function 的模式是已创建。

像这样:

mapping_dispatcher = {1: map_function_1, 2: map_function_2...}

if Validator.validate(document, schema) is True:
    id = schema["schema_id"]

formatted_message = mapping_dispatcher[id](document)

最后的努力可能是简单地对 json 模式进行字符串化并将它们用作键,但我不确定我对此有何看法(感觉很聪明但错误)...

我也可能把这一切都搞错了,但有一种更聪明的方法。

谢谢!

小更新

我通过将模式字符串化,转换为字节,然后转换为十六进制,然后像这样将整数值加在一起来绕过它:

schema_id = 0
bytes_schema = str.encode(schema)
hex_schema = codecs.encode(bytes_schema, "hex") 
for char in hex_schema:
    schema_id += int(char)
>>>schema_id
36832

因此,我只是将模式嵌入到另一个 json 对象中,而不是散列函数,该对象包含如下信息:

[
    {
        "schema_id": "3",
        "schema": {
            "deviceName": {
                "type": "string"
            },
            "tagName": {
                "required": true,
                "type": "string"
            },
            "deviceID": {
                "type": "string"
            },
            "success": {
                "type": "boolean"
            },
            "datatype": {
                "type": "string"
            },
            "timestamp": {
                "required": true,
                "type": "number"
            },
            "value": {
                "required": true,
                "type": "number"
            },
            "registerId": {
                "type": "string"
            },
            "description": {
                "type": "string"
            }
        }
    }
]

我想是想多了。