首页 文章

Avro日期和时间与BigQuery的兼容性?

提问于
浏览
3

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

  • 2

    我在PostgreSQL表中有TIMESTAMP列的数据 . 在遵循https://github.com/spotify/spark-bigquery/issues/19的评论后,我能够通过Avro将其导入BigQuery .

    在Kotlin中使用PostgreSQL JDBC库,我重新计算了Timestamp into BigQuery internal format(自Unix纪元开始以来的微秒)

    (object as java.sql.Timestamp).time * 1000
    

    并将其放入我的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 mk test.test2 dataset.avro schema.json
    

    结果是

    $ 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来说不是问题 .

  • 2

    BigQuery不支持逻辑类型 . BigQuery使用Apache库的C版本 . 我刚检查过,C库还没有对逻辑类型的支持 .

  • 3

    更新:现在支持此功能,请按照issuetracker.google.com/35905894获取更多信息 .

    正如Hua所说,BigQuery不支持Avro逻辑类型,但支持使用时间戳加载Avro数据的方法是使用LONG Avro类型将数据加载到具有TIMESTAMP列的现有BigQuery表中 . 此外,该值应为EPOCH的微秒(不是秒或毫秒) . 例如,下面的Avro文件具有值为1408452095000000的LONG字段,表示“2014-08-19 12:41:35” .

    Avro文件的架构:

    % avro-tools getschema ~/dataset/simple_timestamp.avro
    {
      "type" : "record",
      "name" : "FullName",
      "fields" : [ {
        "name" : "t",
        "type" : "long"
      } ]
    }
    

    将Avro文件加载到具有Timestamp字段的表的示例:

    bq mk --schema t:TIMESTAMP -t vimota.simple_timestamp
    bq load --source_format=AVRO vimota.simple_timestamp ~/dataset/simple_timestamp.avro
    bq head vimota.simple_timestamp:
    
    +---------------------+
    |          t          |
    +---------------------+
    | 2014-08-19 12:41:35 |
    +---------------------+
    

相关问题