protobuf MessageToJson删除值为0的字段

时间:2017-03-23 21:23:45

标签: python json protocol-buffers enumeration

我正在编写一个接收protobufs的Python脚本,将它们转换为json对象,并将它们推送到另一个服务。我使用json.loads(MessageToJson(protobuf))将protobuf转换为python字典对象。后来我用json.dumps(dictionary)将它转换回json。

我有一个带有可选枚举字段的proto,例如:

enum C_TYPE
{
    AB = 0;
    BC = 1;
    CD = 2;
}

当我收到一个带有指定为BC的字段的原型时,一切都按预期工作。当我收到一个带有指定AB字段的原型时,该字段被忽略 - 它不会出现在python字典或后续的json转储中。我找到的解决方法是使用json.loads(MessageToJson(protobuf, including_default_value_fields=True)),但这将为所有缺少的字段创建默认值,而不仅仅是具有0枚举的字段。这意味着枚举0的字段缺失 - 但它不是!

当枚举字段设置为0时,检索枚举字段值的正确方法是什么?

2 个答案:

答案 0 :(得分:2)

没有正确的方法,我错误地定义了我的protobufs。对于枚举字段,第一个值的默认值。这意味着如果protobuf在没有设置值的情况下通过,则会将其设置为默认值,并在转换为json时被忽略(除非您要保留所有默认值。)

因此,建议使用普通名称作为默认值,以便能够正确区分何时设置。即我应该将我的protobuf定义为:

enum C_TYPE
{
    NONE = 0;
    AB = 1;
    BC = 2;
    CD = 3;
}

来自Protobuf Documentation on Optional Fields And Default Values

  

对于枚举,默认值是枚举中列出的第一个值   类型定义。这意味着在添加值时必须小心   枚举值列表的开头。

此外还有issue on golang/protobuf

  

这是按预期工作的。 proto3零值在中省略   JSON格式也是如此。零值应该是"一次性"价值:它   如果序列化消息的发送者设置了,您将看到的内容   字段为无效或无法识别的值。

答案 1 :(得分:0)

在 C++ 的 protobuf 中,可以添加一个选项来始终打印原始字段。 在 MessageToJson 转换中添加此选项会使 protobuf 添加参数,即使它们设置为零。

google::protobuf::util::JsonPrintOptions options;
options.always_print_primitive_fields = true;