You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何将含重复键的元组列表转为符合Zabbix API要求的JSON?

解决Zabbix 3.0 host.create接口重复键JSON的问题

我非常理解你遇到的这个麻烦——Zabbix 3.0的host.create接口在添加多主机组时的格式要求确实有点反常规,必须用重复的groupid键,而不是数组,偏偏Python的字典又不允许重复键,自定义JSONEncoder确实太繁琐了。这里给你几个更简单现成的方案:

方案1:直接构造JSON字符串(最快捷)

如果你的主机组ID是固定的,或者可以动态拼接字符串,直接手写/拼接JSON字符串是最省事的办法,完全绕开Python字典的限制:

import json

# 先构造重复键的groups部分
groups_json_str = '{"groupid": "2", "groupid": "8"}'

# 构造完整的请求数据(如果用requests发送,也可以直接构造整个请求的JSON字符串)
request_payload = {
    "jsonrpc": "2.0",
    "method": "host.create",
    "params": {
        "host": "my_new_host",
        "interfaces": [
            {"type": 1, "main": 1, "useip": 1, "ip": "192.168.0.10", "dns": "", "port": "10050"}
        ],
        # 把提前构造好的重复键JSON字符串转成对象插入
        "groups": json.loads(groups_json_str)
    },
    "auth": "your_auth_token_here",
    "id": 1
}

# 或者直接构造整个请求的JSON字符串,发送时直接传字符串即可
full_request_str = '''{
    "jsonrpc": "2.0",
    "method": "host.create",
    "params": {
        "host": "my_new_host",
        "interfaces": [{"type": 1, "main": 1, "useip": 1, "ip": "192.168.0.10", "dns": "", "port": "10050"}],
        "groups": {"groupid": "2", "groupid": "8"}
    },
    "auth": "your_auth_token_here",
    "id": 1
}'''

这种方法不需要任何复杂的编码逻辑,适合大多数场景——毕竟Zabbix的主机组ID一般不会频繁变动。

方案2:动态生成重复键的JSON片段(适合动态场景)

如果需要动态生成多个groupid,可以用一个简单的工具函数来生成包含重复键的JSON字符串,比自定义JSONEncoder简单太多:

import json

def build_duplicate_key_json(key_value_pairs):
    encoder = json.JSONEncoder()
    # 逐个编码键值对,拼接成JSON对象字符串
    key_value_strings = [f'{encoder.encode(k)}: {encoder.encode(v)}' for k, v in key_value_pairs]
    return '{' + ', '.join(key_value_strings) + '}'

# 动态生成groups的键值对列表
groups_pairs = [("groupid", "2"), ("groupid", "8"), ("groupid", "10")]  # 可以动态添加
groups_json = build_duplicate_key_json(groups_pairs)

# 插入到请求 payload 中
request_payload = {
    "jsonrpc": "2.0",
    "method": "host.create",
    "params": {
        "host": "my_dynamic_host",
        "interfaces": [{"type": 1, "main": 1, "useip": 1, "ip": "192.168.0.11", "dns": "", "port": "10050"}],
        "groups": json.loads(groups_json)
    },
    "auth": "your_auth_token_here",
    "id": 1
}

这个方法通过手动拼接JSON片段,完美绕过了Python字典的键唯一性限制,而且代码量很小,比自定义编码器简洁多了。

为什么你之前的方法不行?

你尝试的SameKeys类方案失效,是因为Python判断字典键的唯一性是基于哈希值和相等性——两个SameKeys("groupid")实例的哈希值相同,所以后面的键值对会直接覆盖前面的,最终字典里只会保留最后一个值,这就是你print(a)时看不到两个键的原因。


内容的提问来源于stack exchange,提问作者Константин Велопокатуновичь

火山引擎 最新活动