如果子消息没有字段,如何在 protobuf 消息上分配 oneof 字段?

问题描述 投票:0回答:2

我想创建一个 BigTable

DeleteFromRow
突变。
Mutation
DeleteFromRow
的原型如下所示:

oneof mutation {
    // Set a cells value.
    SetCell set_cell = 1;

    // Deletes cells from a column.
    DeleteFromColumn delete_from_column = 2;

    // Deletes cells from a column family.
    DeleteFromFamily delete_from_family = 3;

    // Deletes cells from the entire row.
    DeleteFromRow delete_from_row = 4;
}

    message DeleteFromRow {
}

在 Python 中,您无法直接实例化

DeleteFromRow
对象并将
delete_from_row
Mutation
字段设置为该对象。

所以这不起作用

request = bigtable_pb2.MutateRowRequest(table_name='tablename', row_key=row_key)
mutation = request.mutations.add()
mutation.delete_from_row = data_pb2.Mutation.DeleteFromRow()

正如其他 SO 用户提出的那样(参见这个问题),这会导致

AttributeError: Assignment not allowed to composite field "delete_from_row" in protocol message object.

根据 protobuf 文档,您应该通过设置子字段之一来设置 oneof 字段。因此,应该以这种方式创建

DeleteFromFamily
突变:

mutation.delete_from_family.family_name = 'some_family'

但是,对于没有字段的DeleteFromRow 消息,我该如何执行此操作?

python grpc bigtable
2个回答
3
投票

您可以使用Message.SetInParent

将此标记为存在于父级中。

当您分配子消息的字段时,这通常会自动发生,但有时您希望使子消息显示,同时将其保留为空。如果您发现自己在使用它,您可能需要重新考虑您的设计。

示例:

message Msg {
  oneof kind {
    int64 int_field = 1;
    EmptyMsg msg_field = 1;
  }
}

message EmptyMsg {}
msg = Msg()
print(msg.WhichOneof('kind'))  # None

msg.msg_field  # No-op (return EmptyMsg but don't set oneof field)
print(msg.WhichOneof('kind'))  # None

msg.msg_field.SetInParent()
print(v.WhichOneof('kind'))  # msg_field

2
投票

您可以启动

DeleteFromRow
对象并使用关键字参数
delete_from_row
:

创建突变
dfr = data_pb2.Mutation.DeleteFromRow()
mutation = data_pb2.Mutation(delete_from_row=dfr)

虽然您不能

add
append
对请求的重复突变字段进行此突变(尽管在我看来这就是文档所说的这里),但您可以
extend
它:

request = bigtable_pb2.MutateRowRequest(table_name='tablename', row_key=row_key)
request.mutations.extend([mutation])
© www.soinside.com 2019 - 2024. All rights reserved.