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

时间:2016-11-17 10:03:25

标签: google-bigquery avro

BigQuery通常可以很好地加载Avro数据,但是“bq load”在时间戳和使用Avro logicalType属性的其他日期/时间字段方面遇到了很多麻烦。

  1. 当BigQuery TIMESTAMP将它们解释为微秒时间戳(关闭1000)时,我的Avro类型timestamp-millis数据会被破坏。
  2. 可以加载到TIMESTAMP中的时间戳 - 微整数在BigQuery DATETIME中变为INVALID。我无法找到https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types
  3. 的有效内容的解释
  4. ISO8601格式的字符串无法加载到TIMESTAMP或DATETIME(不兼容的类型错误)但我认为如果我加载普通的JSON,BigQuery会支持它。
  5. Avro“date”类型无法加载到DATE(也是不兼容的类型)。
  6. 我想我总是可以通过将数据加载到临时字段并使用查询到CAST或将它们转换为其他字段来解决这些问题,但这不会扩展或支持模式演变或流式传输。使用定义良好的模式在Avro中生成数据应该避免为不同的消费者再次转换数据的额外步骤。

    BigQuery真的与Avro日期和时间不兼容吗? (或者我做的事情是愚蠢的)

    或者“bq加载”问题在这里?有没有更好的方法来加载Avro数据?

4 个答案:

答案 0 :(得分:5)

更新:现在支持此功能,请点击issuetracker.google.com/35905894了解详情。

正如Hua所说,BigQuery不支持Avro逻辑类型,但是加载带有时间戳的Avro数据的支持方式是使用LONG Avro类型将数据加载到具有TIMESTAMP列的现有BigQuery表中。此外,该值应为EPOCH的微秒(不是秒或毫秒)。例如,下面的Avro文件有一个LONG字段,其值为1408452095000000,表示“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 |
+---------------------+

答案 1 :(得分:3)

现在可以为所有BigQuery用户公开了解Avro Logical Types的原生理解。有关详细信息,请参阅此处的文档页面:https://cloud.google.com/bigquery/docs/loading-data-cloud-storage-avro#logical_types

答案 2 :(得分:2)

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

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

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

并将其放入我的Schema.Type.LONG类型的avro记录中。

然后我created a schema file for my data in JSON我给了#34;时间戳"的列类型。

[ {"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来说不是问题。

答案 3 :(得分:1)

我们遇到了同样的问题并解决了。用于将日期数据导入现有的 DATE 类型的 BQ 表字段的 Avro 架构如下。日期值的整数值必须是自纪元以来的天数(不是秒)。请注意使用嵌套格式的架构类型定义的样式。

  1. 我创建了一个 BQ 表,其中包含一个名为“day”的字段,类型为 DATE,mode=REQUIRED。
  2. 我使用以下架构创建了一个 Avro 文件,其中有一条记录包含数天的整数值 18639
  3. 我将该 Avro 文件上传到 GCS 中的存储桶
  4. 我使用以下命令将 Avro 数据加载到表中,并在我在表中查看时将其转换为 BQ DATE 类型:

bq load --source_format AVRO --use_avro_logical_types s1.avro_date gs://bucket_name/bq_date_int_logical_nested.avro

echo "select * from s1.avro_date" | bq query

Waiting on bqjob_r1433d5cfa5eb9a89_00000176f3182f03_1 ... (0s) Current status: DONE   
+------------+
|    day     |
+------------+
| 2021-01-12 |
+------------+

使用的架构:

{
  "type" : "record",
  "name" : "bq_date",
  "namespace" : "my.namespace",
  "fields" : [{
      "name" : "day",
      "type" : {
        "type" : "int",
        "logicalType" : "date"
      }
    } 
  ]
}

FWIW:我们测试了使用 Avro Python 1.10.1 和 Java 库创建的测试文件。