如果子消息没有字段,如何在 protobuf 消息上分配 oneof 字段?
Posted
技术标签:
【中文标题】如果子消息没有字段,如何在 protobuf 消息上分配 oneof 字段?【英文标题】:How do I assign a oneof field on a protobuf message if the child message has no fields? 【发布时间】:2018-06-11 08:23:52 【问题描述】:我想创建一个 BigTable DeleteFromRow
突变。 Mutation
和 DeleteFromRow
的原型如下所示:
oneof mutation
// Set a cell's 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
对象并将 Mutation
的 delete_from_row
字段设置为该对象。
所以这行不通:
request = bigtable_pb2.MutateRowRequest(table_name='tablename', row_key=row_key)
mutation = request.mutations.add()
mutation.delete_from_row = data_pb2.Mutation.DeleteFromRow()
正如其他 SO 用户提出的(请参阅 this question),这会导致
AttributeError: Assignment not allowed to composite field "delete_from_row" in protocol message object.
根据protobuf docs,您应该通过设置一个子字段来设置一个oneof字段。所以应该这样创建一个DeleteFromFamily
突变:
mutation.delete_from_family.family_name = 'some_family'
但是,对于没有字段的DeleteFromRow
消息,我该如何处理?
【问题讨论】:
出于好奇,你为什么不用官方客户端? 因为它不完整。它是这个 grpc 实现之上的抽象。特别是,当我想根据一组行键或一组行键前缀读取行时,我切换到允许您在单个请求中执行此操作的底层 grpc 客户端。 知道了。 FWIW,我们现在正在开发该功能。 【参考方案1】:你可以使用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
对请求的重复突变字段进行这种突变(尽管在我看来这是文档所说的 here),但您可以 extend
它:
request = bigtable_pb2.MutateRowRequest(table_name='tablename', row_key=row_key)
request.mutations.extend([mutation])
【讨论】:
关于该文档的链接:Repeated Field
和 Repeated Message Field
之间存在差异。后者没有 append
功能 - 如文档所述。以上是关于如果子消息没有字段,如何在 protobuf 消息上分配 oneof 字段?的主要内容,如果未能解决你的问题,请参考以下文章