使用可序列化函数读取大查询 - 如何从 GenericRecord 获取 NUMERIC 类型

Posted

技术标签:

【中文标题】使用可序列化函数读取大查询 - 如何从 GenericRecord 获取 NUMERIC 类型【英文标题】:Big Query Read using Serializable Function - How to get NUMERIC type from GenericRecord 【发布时间】:2020-06-10 13:28:51 【问题描述】:

嗨,

我正在使用 Beam 从 BQ 表中读取数据,发现使用 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-的示例

我的 Big Query 列是:

|Field name | Field type|
|Date_Time  | TIMESTAMP |
|Simple_Id  | STRING    |
|A_Price    | NUMERIC   |

我的代码如下:

公共类 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)));

我不确定是否使用了 Coder。 ProtoValueType 是一个 protobuf 生成的绑定类。

我的问题是:如何从 GenericRecord(我认为是 Avro 对象)中获取 NUMERIC 类型的值?

任何帮助表示赞赏。我可以使用 readTableRows() 获取该行,它都以字符串形式返回,所以我不想理解该方法。

【问题讨论】:

只是为了澄清,您正在从 BigQuery 中读取,您在哪里写入输出? 您好 Alexandre,我正在从 BigQuery 读取数据并将行转换为 protobuf 对象,我将传递给另一个函数(例如,平均 aPrice 值)。输出可以是平均值,也可以是其他东西(仍在编写管道)。 【参考方案1】:

NUMERIC 字段对应的GenericRecord 字段具有一些附加属性,您可以使用这些属性将NUMERIC 解析为java.math.BigDecimal

此类字段的架构类型为BYTES,类似于以下内容:

"type":"bytes","logicalType":"decimal","precision":38,"scale":9

我刚刚发布了一篇博文,解释了如何使用架构中的这些属性将字节数组转换为java.math.BigDecimal

https://medium.com/@iht/reading-numeric-fields-with-bigqueryio-in-apache-beam-23273a9d0c99

【讨论】:

感谢以色列,这正是我想要的!不知道如何“批准”或投票给答案,但案例已关闭。 ;) 我认为你可以接受我的回答作为“你的问题的答案”。更多信息在这里:***.com/help/someone-answers 再次感谢以色列!完成;)

以上是关于使用可序列化函数读取大查询 - 如何从 GenericRecord 获取 NUMERIC 类型的主要内容,如果未能解决你的问题,请参考以下文章

从aspx网页读取xml

在大查询中查找从特定数字开始的序列

如何在读取之前测试存储中是不是存在可序列化对象?

如何使用带有可空值的吸气剂?

如何从大查询中获取多个查询的所有结果?

一个数据表如果同时写入同时读取 会影响表的查询速度吗,如何优化大数据量表,比如1000万条用户记录