Thank you Lars and thank you Luke!

On Wed, Jul 8, 2020 at 9:33 PM Luke Cwik <lc...@google.com> wrote:

> The deprecated method is not going to be removed anytime soon so I
> wouldn't worry about it being removed.
>
> If you really want to use non-deprecated methods, then the
> TableRowJsonCoder uses the StringUtf8Coder to parse strings so it is
> looking for a nested encoding using the StringUtf8Coder encoding. So
> something like this:
> ByteArrayOutputStream baos = new ...
> StringUtf8Coder.of().encode(jsonString, baos);
> TableRow row = TableRowJsonCoder.of().decode(new
> ByteArrayInputStream(baos.toByteArray()));
>
> But why use a coder at all? TableRowJsonCoder is a thin wrapper around
> using Jackson's ObjectMapper to perform the conversion. So you could do
> something like:
> ObjectMapper mapper = new
> ObjectMapper().disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
> TableRow row = mapper.readValue(strValue, TableRow.class);
>
>
> On Wed, Jul 8, 2020 at 7:57 AM Lars Almgren Schwartz <
> lars.almg...@tink.com> wrote:
>
>> Hey,
>>
>> Don't know if it's the official way but we have written our own proto to
>> BigQuery converter which works pretty well.
>>
>> public static TableRow convertEventToTableRow(TableRow tableRow, Message 
>> event) {
>>     Map<Descriptors.FieldDescriptor, Object> fields = event.getAllFields();
>>     for (Descriptors.FieldDescriptor field : fields.keySet()) {
>>         tableRow = mapToBigQueryField(tableRow, field, fields.get(field));
>>     }
>>
>>     return tableRow;
>> }
>>
>> private static TableRow mapToBigQueryField(
>>         TableRow tableRow, Descriptors.FieldDescriptor field, Object value) {
>>     Descriptors.FieldDescriptor.JavaType fieldType = field.getJavaType();
>>     switch (fieldType) {
>>         case INT:
>>         case LONG:
>>         case FLOAT:
>>         case DOUBLE:
>>         case BOOLEAN:
>>             return tableRow.set(field.getName(), value);
>>         case BYTE_STRING:
>>             if (field.isRepeated()) {
>>                 return tableRow.set(
>>                         field.getName(),
>>                         processRepeatedField(
>>                                 value,
>>                                 x ->
>>                                         Base64.getEncoder()
>>                                                 .encodeToString(
>>                                                         ((ByteString) 
>> x).toByteArray())));
>>             } else {
>>                 return tableRow.set(
>>                         field.getName(),
>>                         Base64.getEncoder().encodeToString(((ByteString) 
>> value).toByteArray()));
>>             }
>>         case ENUM:
>>             if (field.isRepeated()) {
>>                 return tableRow.set(
>>                         field.getName(), processRepeatedField(value, x -> 
>> x.toString()));
>>             } else {
>>                 return tableRow.set(field.getName(), value.toString());
>>             }
>>         case STRING:
>>             if (isUUIDField(field.getName())) {
>>                 if (field.isRepeated()) {
>>                     return tableRow.set(
>>                             field.getName(),
>>                             processRepeatedField(
>>                                     value, x -> 
>> UUIDUtil.getBase64FromUUID((String) x)));
>>                 } else {
>>                     return tableRow.set(
>>                             field.getName(), 
>> UUIDUtil.getBase64FromUUID((String) value));
>>                 }
>>             } else {
>>                 return tableRow.set(field.getName(), value);
>>             }
>>         case MESSAGE:
>>             switch (field.getMessageType().getFullName()) {
>>                     // Map well known message types that we have a specific 
>> mapping for.
>>                 case "google.protobuf.Timestamp":
>>                     if (field.isRepeated()) {
>>                         return tableRow.set(
>>                                 field.getName(),
>>                                 processRepeatedField(
>>                                         value,
>>                                         x ->
>>                                                 
>> com.google.cloud.Timestamp.fromProto(
>>                                                                 (Timestamp) 
>> x)
>>                                                         .toString()));
>>                     } else {
>>                         return tableRow.set(
>>                                 field.getName(),
>>                                 
>> com.google.cloud.Timestamp.fromProto((Timestamp) value)
>>                                         .toString());
>>                     }
>>                 case "xxx.xxx.ExactNumber":
>>                     if (field.isRepeated()) {
>>                         return tableRow.set(
>>                                 field.getName(),
>>                                 processRepeatedField(
>>                                         value, x -> 
>> NumberUtils.toString((ExactNumber) x)));
>>                     } else {
>>                         return tableRow.set(
>>                                 field.getName(), 
>> NumberUtils.toString((ExactNumber) value));
>>                     }
>>                 case "google.protobuf.UInt64Value":
>>                     if (field.hasDefaultValue()) {
>>                         break;
>>                     } else if (value.equals(
>>                             
>> com.google.protobuf.UInt64Value.getDefaultInstance())) {
>>                         value = 0;
>>                         return tableRow.set(field.getName(), value);
>>                     } else {
>>                         return tableRow.set(field.getName(), ((UInt64Value) 
>> value).getValue());
>>                     }
>>                 case "google.protobuf.Int32Value":
>>                     if (field.hasDefaultValue()) {
>>                         break;
>>                     } else if (value.equals(
>>                             
>> com.google.protobuf.Int32Value.getDefaultInstance())) {
>>                         value = 0;
>>                         return tableRow.set(field.getName(), value);
>>                     } else {
>>                         return tableRow.set(field.getName(), ((Int32Value) 
>> value).getValue());
>>                     }
>>                 case "google.protobuf.DoubleValue":
>>                     if (field.hasDefaultValue()) {
>>                         break;
>>                     } else if (value.equals(
>>                             
>> com.google.protobuf.DoubleValue.getDefaultInstance())) {
>>                         value = 0;
>>                         return tableRow.set(field.getName(), value);
>>                     } else {
>>                         return tableRow.set(field.getName(), ((DoubleValue) 
>> value).getValue());
>>                     }
>>                 case "google.protobuf.FloatValue":
>>                     if (field.hasDefaultValue()) {
>>                         break;
>>                     } else if (value.equals(
>>                             
>> com.google.protobuf.FloatValue.getDefaultInstance())) {
>>                         value = 0;
>>
>>                         return tableRow.set(field.getName(), value);
>>                     } else {
>>                         return tableRow.set(field.getName(), ((FloatValue) 
>> value).getValue());
>>                     }
>>                 case "google.protobuf.Int64Value":
>>                     if (field.hasDefaultValue()) {
>>                         break;
>>                     } else if (value.equals(
>>                             
>> com.google.protobuf.Int64Value.getDefaultInstance())) {
>>                         value = 0;
>>                         return tableRow.set(field.getName(), value);
>>                     } else {
>>                         return tableRow.set(field.getName(), ((Int64Value) 
>> value).getValue());
>>                     }
>>                 case "google.protobuf.UInt32Value":
>>                     if (field.hasDefaultValue()) {
>>                         break;
>>                     } else if (value.equals(
>>                             
>> com.google.protobuf.UInt32Value.getDefaultInstance())) {
>>                         value = 0;
>>                         return tableRow.set(field.getName(), value);
>>                     } else {
>>                         return tableRow.set(field.getName(), ((UInt32Value) 
>> value).getValue());
>>                     }
>>                 case "google.protobuf.BoolValue":
>>                     if (field.hasDefaultValue()) break;
>>                     else if 
>> (value.equals(com.google.protobuf.BoolValue.getDefaultInstance())) {
>>                         value = false;
>>                         return tableRow.set(field.getName(), value);
>>                     } else {
>>                         return tableRow.set(field.getName(), ((BoolValue) 
>> value).getValue());
>>                     }
>>                 case "google.protobuf.StringValue":
>>                     if (field.hasDefaultValue()) {
>>                         break;
>>                     } else if (value.equals(
>>                             
>> com.google.protobuf.StringValue.getDefaultInstance())) {
>>                         value = "";
>>                         return tableRow.set(field.getName(), value);
>>                     } else if (isUUIDField(field.getName())) {
>>                         if (field.isRepeated()) {
>>                             return tableRow.set(
>>                                     field.getName(),
>>                                     processRepeatedField(
>>                                             value,
>>                                             x ->
>>                                                     
>> UUIDUtil.getBase64FromUUID(
>>                                                             ((StringValue) 
>> x).getValue())));
>>                         } else {
>>                             return tableRow.set(
>>                                     field.getName(),
>>                                     UUIDUtil.getBase64FromUUID(
>>                                             ((StringValue) 
>> value).getValue()));
>>                         }
>>                     } else if (field.isRepeated()) {
>>                         return tableRow.set(
>>                                 field.getName(),
>>                                 processRepeatedField(value, x -> 
>> ((StringValue) x).getValue()));
>>                     } else {
>>                         return tableRow.set(field.getName(), ((StringValue) 
>> value).getValue());
>>                     }
>>                 case "google.protobuf.BytesValue":
>>                     if (field.hasDefaultValue()) {
>>                         break;
>>                     } else if (value.equals(
>>                             
>> com.google.protobuf.BytesValue.getDefaultInstance())) {
>>                         value = ByteString.EMPTY;
>>                         return tableRow.set(field.getName(), value);
>>                     } else if (field.isRepeated()) {
>>                         return tableRow.set(
>>                                 field.getName(),
>>                                 processRepeatedField(
>>                                         value,
>>                                         x ->
>>                                                 Base64.getEncoder()
>>                                                         .encodeToString(
>>                                                                 
>> ((BytesValue) x)
>>                                                                         
>> .getValue()
>>                                                                         
>> .toByteArray())));
>>                     } else {
>>                         return tableRow.set(
>>                                 field.getName(),
>>                                 Base64.getEncoder()
>>                                         .encodeToString(
>>                                                 ((BytesValue) 
>> value).getValue().toByteArray()));
>>                     }
>>                 default:
>>                     if (field.isRepeated()) {
>>                         return tableRow.set(
>>                                 field.getName(),
>>                                 processRepeatedField(
>>                                         value,
>>                                         x ->
>>                                                 convertEventToTableRow(
>>                                                         new TableRow(), 
>> (Message) x)));
>>                     } else {
>>                         return tableRow.set(
>>                                 field.getName(),
>>                                 convertEventToTableRow(new TableRow(), 
>> (Message) value));
>>                     }
>>             }
>>         default:
>>             throw new IllegalArgumentException(
>>                     field.getFullName() + " has an unsupported type " + 
>> field.getType());
>>     }
>> }
>>
>>
>> On Wed, Jul 8, 2020 at 4:40 PM Kaymak, Tobias <tobias.kay...@ricardo.ch>
>> wrote:
>>
>>> As a workaround I am currently using the following code to generate a
>>> TableRow object from a Java Protobuf class - as I am facing a problem with
>>> Beam schemas (
>>> https://www.mail-archive.com/user@beam.apache.org/msg05799.html).
>>>
>>> It relies on the TableRowJsonCoder:
>>>
>>>       String json =
>>> JsonFormat.printer().omittingInsignificantWhitespace()
>>>           .preservingProtoFieldNames().print(article.toBuilder());
>>>       InputStream inputStream = new
>>> ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8));
>>>
>>>       TableRow tableRow = TableRowJsonCoder.of().decode(inputStream,
>>> Coder.Context.OUTER);
>>>
>>> However, the usage of Coder.Context is deprecated - I've tried to
>>> simply use the decode(), but that defaults to Context.NESTED.
>>>
>>> What is the correct way of doing this?
>>>
>>> Best,
>>> Tobi
>>>
>>

Reply via email to