Big Query Read using Serializable Function - 如何从 GenericRecord 获取 NUMERIC 类型
Big Query Read using Serializable Function - How to get NUMERIC type from GenericRecord
嗨,
我正在使用 Beam 从 BQ 中读取 table,发现使用 SerializableFunction 的 read() 比 readTableRows() 具有更好的性能。按照 https://beam.apache.org/releases/javadoc/2.20.0/org/apache/beam/sdk/io/gcp/bigquery/BigQueryIO.html#read-org.apache.beam.sdk.transforms.SerializableFunction-
中的示例
我的大查询列是:
|Field name | Field type|
|Date_Time | TIMESTAMP |
|Simple_Id | STRING |
|A_Price | NUMERIC |
我的代码如下:
public class ConvertBQSchemaRecordToProtoDataFn
实现 SerializableFunction {
@Override
public ProtoValueType apply(SchemaAndRecord schemaAndRecord) {
GenericRecord avroRecord = schemaAndRecord.getRecord();
long dateTimeMillis = (Long) avroRecord.get("Date_Time");
String simpleId = avroRecord.get("Simple_Id").toString();
double aPrice = convertToDouble(avroRecord.get("A_Price").toString());
long 和 String 没问题。但是,当我尝试转换 NUMERIC 类型时,GenericRecord(来自调试器)将其显示为您无法转换的 HeapByteBuffer。我不确定如何获得 "A_Price":
的值
debug
调用管道代码如下所示:
PCollection<ProtoValueType> protoData =
pipeline.apply("BigQuery Read",
BigQueryIO.read(new ConvertBQSchemaRecordToProtoDataFn())
.fromQuery(sqlQuery)
.usingStandardSql()
.withCoder(ProtoCoder.of(ProtoValueType.class)));
我不确定是否使用了编码器。 ProtoValueType 是一个 protobuf 生成的绑定 class.
我的问题是:如何从 GenericRecord(我认为它是一个 Avro 对象)中获取 NUMERIC 类型的值?
感谢任何帮助。我可以使用 readTableRows() 获取行,所有返回的都是字符串,所以我不想理解该方法。
对应于 NUMERIC
字段的 GenericRecord 字段有一些额外的属性,您可以使用这些属性将 NUMERIC
解析为 java.math.BigDecimal
。
此类字段的架构将是 BYTES
类型,类似于以下内容:
{"type":"bytes","logicalType":"decimal","precision":38,"scale":9}
我刚刚发布了一篇博客 post 解释了如何在模式中使用这些属性将字节数组转换为 java.math.BigDecimal
:
https://medium.com/@iht/reading-numeric-fields-with-bigqueryio-in-apache-beam-23273a9d0c99
嗨,
我正在使用 Beam 从 BQ 中读取 table,发现使用 SerializableFunction 的 read() 比 readTableRows() 具有更好的性能。按照 https://beam.apache.org/releases/javadoc/2.20.0/org/apache/beam/sdk/io/gcp/bigquery/BigQueryIO.html#read-org.apache.beam.sdk.transforms.SerializableFunction-
我的大查询列是:
|Field name | Field type|
|Date_Time | TIMESTAMP |
|Simple_Id | STRING |
|A_Price | NUMERIC |
我的代码如下:
public class ConvertBQSchemaRecordToProtoDataFn 实现 SerializableFunction {
@Override
public ProtoValueType apply(SchemaAndRecord schemaAndRecord) {
GenericRecord avroRecord = schemaAndRecord.getRecord();
long dateTimeMillis = (Long) avroRecord.get("Date_Time");
String simpleId = avroRecord.get("Simple_Id").toString();
double aPrice = convertToDouble(avroRecord.get("A_Price").toString());
long 和 String 没问题。但是,当我尝试转换 NUMERIC 类型时,GenericRecord(来自调试器)将其显示为您无法转换的 HeapByteBuffer。我不确定如何获得 "A_Price":
的值debug
调用管道代码如下所示:
PCollection<ProtoValueType> protoData =
pipeline.apply("BigQuery Read",
BigQueryIO.read(new ConvertBQSchemaRecordToProtoDataFn())
.fromQuery(sqlQuery)
.usingStandardSql()
.withCoder(ProtoCoder.of(ProtoValueType.class)));
我不确定是否使用了编码器。 ProtoValueType 是一个 protobuf 生成的绑定 class.
我的问题是:如何从 GenericRecord(我认为它是一个 Avro 对象)中获取 NUMERIC 类型的值?
感谢任何帮助。我可以使用 readTableRows() 获取行,所有返回的都是字符串,所以我不想理解该方法。
对应于 NUMERIC
字段的 GenericRecord 字段有一些额外的属性,您可以使用这些属性将 NUMERIC
解析为 java.math.BigDecimal
。
此类字段的架构将是 BYTES
类型,类似于以下内容:
{"type":"bytes","logicalType":"decimal","precision":38,"scale":9}
我刚刚发布了一篇博客 post 解释了如何在模式中使用这些属性将字节数组转换为 java.math.BigDecimal
:
https://medium.com/@iht/reading-numeric-fields-with-bigqueryio-in-apache-beam-23273a9d0c99