如果子消息没有字段,如何在 protobuf 消息上分配一个字段?
How do I assign a oneof field on a protobuf message if the child message has no fields?
我想创建一个 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,您应该通过设置子字段之一来设置一个字段。因此,应该以这种方式创建 DeleteFromFamily
突变:
mutation.delete_from_family.family_name = 'some_family'
但是,如何为没有字段的 DeleteFromRow
消息执行此操作?
您可以启动 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])
您可以使用 Message.SetInParent:
Mark this as present in the parent.
This normally happens automatically when you assign a field of a sub-message, but sometimes you want to make the sub-message present while keeping it empty. If you find yourself using this, you may want to reconsider your design.
示例:
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
我想创建一个 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,您应该通过设置子字段之一来设置一个字段。因此,应该以这种方式创建 DeleteFromFamily
突变:
mutation.delete_from_family.family_name = 'some_family'
但是,如何为没有字段的 DeleteFromRow
消息执行此操作?
您可以启动 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])
您可以使用 Message.SetInParent:
Mark this as present in the parent.
This normally happens automatically when you assign a field of a sub-message, but sometimes you want to make the sub-message present while keeping it empty. If you find yourself using this, you may want to reconsider your design.
示例:
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