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