pythongrpcbigtable

How do I assign a oneof field on a protobuf message if the child message has no fields?


I want to create a BigTable DeleteFromRow mutation. The proto for the Mutation and the DeleteFromRow looks like this:

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 {
}

In Python, you cannot directly instantiate a DeleteFromRow object and set the delete_from_row field of the Mutation to that object.

So this does not work:

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

As raised by other SO users (see this question), that results in a

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

According to the protobuf docs, you should set a oneof field by setting one of the child fields. So a DeleteFromFamily mutation should be created this way:

mutation.delete_from_family.family_name = 'some_family'

However, how do I do this for the DeleteFromRow message which has no fields?


Solution

  • You can initiate the DeleteFromRow object and create a mutation with the keyword argument delete_from_row:

    dfr = data_pb2.Mutation.DeleteFromRow()
    mutation = data_pb2.Mutation(delete_from_row=dfr)
    

    While you cannot add or append this mutation to the repeated mutations field of a request (although it appears to me that that is what the docs says here), you can extend it:

    request = bigtable_pb2.MutateRowRequest(table_name='tablename', row_key=row_key)
    request.mutations.extend([mutation])