BigQuery通常可以很好地加载Avro数据,但是“bq load”在时间戳和使用Avro logicalType属性的其他日期/时间字段方面遇到了很多麻烦 .
-
当BigQuery TIMESTAMP将它们解释为微秒时间戳(关闭1000)时,我的Avro类型timestamp-millis数据被破坏 .
-
可加载到TIMESTAMP中的时间戳 - 微整数在BigQuery DATETIME中变为INVALID . 我无法找到有关https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types的有效内容的解释
-
ISO8601格式的字符串无法加载到TIMESTAMP或DATETIME(不兼容的类型错误)但我认为如果我加载普通的JSON,BigQuery会支持 .
-
Avro "date"类型无法加载到DATE(也是不兼容的类型) .
我想我可以通过始终将数据加载到临时字段并使用查询到CAST或将它们转换为其他字段来解决这些问题,但这不会扩展或支持模式演变或流式传输 . 使用定义良好的模式在Avro中生成数据应该避免为不同的消费者再次转换数据的额外步骤 .
BigQuery真的与Avro日期和时间不兼容吗? (或者我做的事情是愚蠢的)
或者“bq加载”问题在这里?有没有更好的方法来加载Avro数据?
3 回答
我在PostgreSQL表中有TIMESTAMP列的数据 . 在遵循https://github.com/spotify/spark-bigquery/issues/19的评论后,我能够通过Avro将其导入BigQuery .
在Kotlin中使用PostgreSQL JDBC库,我重新计算了Timestamp into BigQuery internal format(自Unix纪元开始以来的微秒)
并将其放入我的avro记录中,类型为
Schema.Type.LONG
.然后我created a schema file for my data in JSON我给了"timestamp"的列类型 .
[ {"name": "job", "type": "string", "mode": "required"}, ... {"name": "began", "type": "timestamp", "mode": "required"}, ... ]
(见开始字段)
最后,我将它导入到BigQuery中
结果是
$ bq head test.test2 +------+----+----------+---------------------+---------+-----------+ | job | id | duration | began | status | node_name | +------+----+----------+---------------------+---------+-----------+ | job1 | 1 | 0.0 | 2012-04-01 00:00:00 | aStatus | aNodeName | | job2 | 1 | 0.0 | 2020-02-02 00:02:02 | aStatus | aNodeName | +------+----+----------+---------------------+---------+-----------+
Web UI不允许为Avro文件指定架构,但CLI客户端和API可以指定架构 .
我仍然遇到的唯一问题是处理时区 . 但这对Avro来说不是问题 .
BigQuery不支持逻辑类型 . BigQuery使用Apache库的C版本 . 我刚检查过,C库还没有对逻辑类型的支持 .
更新:现在支持此功能,请按照issuetracker.google.com/35905894获取更多信息 .
正如Hua所说,BigQuery不支持Avro逻辑类型,但支持使用时间戳加载Avro数据的方法是使用LONG Avro类型将数据加载到具有TIMESTAMP列的现有BigQuery表中 . 此外,该值应为EPOCH的微秒(不是秒或毫秒) . 例如,下面的Avro文件具有值为1408452095000000的LONG字段,表示“2014-08-19 12:41:35” .
Avro文件的架构:
将Avro文件加载到具有Timestamp字段的表的示例: