googleapis / proto-plus-python

Beautiful, idiomatic protocol buffers in Python
Apache License 2.0
171 stars 36 forks source link

Setting struct.Value message attributes? #104

Closed busunkim96 closed 4 years ago

busunkim96 commented 4 years ago

How do you set 'values' for the message below?

class Row(proto.Message):
    r"""A representation of a row in a relational table.

    Attributes:
        column_spec_ids (Sequence[str]):
            The resource IDs of the column specs describing the columns
            of the row. If set must contain, but possibly in a different
            order, all input feature

            [column_spec_ids][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs]
            of the Model this row is being passed to. Note: The below
            ``values`` field must match order of this field, if this
            field is set.
        values (Sequence[~.struct.Value]):
            Required. The values of the row cells, given in the same
            order as the column_spec_ids, or, if not set, then in the
            same order as input feature

            [column_specs][google.cloud.automl.v1beta1.TablesModelMetadata.input_feature_column_specs]
            of the Model this row is being passed to.
    """

    column_spec_ids = proto.RepeatedField(proto.STRING, number=2)

    values = proto.RepeatedField(proto.MESSAGE, number=3, message=struct.Value,)

Things I've tried:

>>> row = Row()
>>> values = [struct_pb2.Value(string_value="hello")]
>>> values
[string_value: "hello"
]
>>> row.values=values
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/google/home/busunkim/github/python-automl/.nox/unit-3-8/lib/python3.8/site-packages/proto/message.py", line 543, in __setattr__
    self._pb.MergeFrom(self._meta.pb(**{key: pb_value}))
TypeError: Value must be iterable
software-dov commented 4 years ago

What I think is going on is that the marshalling is getting confused: it thinks the list of Values is itself a singular listvalue, and trying to set a repeated field to a single element generates an error.

Workaround is to append elements individually:

row = Row()
values = [struct_pb2.Value(string_value="hello")]
for v in values:
    row.values.append(v)
busunkim96 commented 4 years ago

Converting to a docs issue to document in the proto-plus docs how to hold struct.Value