【问题标题】:Compatibility of Avro dates and times with BigQuery?Avro 日期和时间与 BigQuery 的兼容性?
【发布时间】:2017-03-31 19:36:26
【问题描述】:

BigQuery 通常可以很好地加载 Avro 数据,但“bq load”在时间戳和其他使用 AvrologicalType 属性的日期/时间字段方面存在很多问题。

  1. 当 BigQuery TIMESTAMP 将我的 Avro 类型 timestamp-millis 数据解释为微秒时间戳(相差 1000)时,我的数据被破坏了。
  2. 可以加载到 TIMESTAMP 中的时间戳微整数在 BigQuery DATETIME 中变为无效。我在https://cloud.google.com/bigquery/docs/reference/standard-sql/data-types 找不到有效的解释
  3. ISO8601 格式的字符串无法加载到 TIMESTAMP 或 DATETIME(不兼容类型错误),但我认为如果我加载纯 JSON,BigQuery 会支持这一点。
  4. Avro“日期”类型无法加载到 DATE(也是不兼容的类型)。

我想我可以通过始终将数据加载到临时字段并使用 CAST 查询或将它们转换为其他字段来解决这些问题,但这不能很好地扩展或支持架构演变或流式传输。在 Avro 中使用定义明确的模式生成数据应该避免为不同的消费者再次转换数据的额外步骤。

BigQuery 真的与 Avro 日期和时间不兼容吗? (或者我在做什么蠢事)

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

【问题讨论】:

  • 拥有一个示例文件可以帮助调试这个问题(如果是错误,请在此处发布code.google.com/p/google-bigquery/issues/list
  • 我不知道这是一个错误还是 BigQuery 只是不支持将 Avro 数据加载到 TIMESTAMP、DATETIME 和 DATE 数据类型中。 cloud.google.com/bigquery/data-formats#avro_format 没有提到这三种类型中的任何一种。我不确定如何在此处附加二进制 Avro 数据文件..
  • 现在支持此功能,请关注 issuetracker.google.com/35905894 了解更多信息。

标签: google-bigquery avro


【解决方案1】:

更新:现在支持此功能,请关注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 文件加载到带有时间戳字段的表的示例:

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 |
+---------------------+

【讨论】:

  • 您知道如何将 avro 数据(日期)加载到具有 date 类型的 BigQuery 中吗?我尝试使用 avro 字符串但失败了。例如2018-11-29
  • @Sugimiyantosuma 你可以使用 Avro 的日期逻辑类型 (avro.apache.org/docs/1.8.0/spec.html#Date) 吗?如果您被列入白名单或使用 useAvroLogicalTypes 标志,BigQuery 现在原生支持此功能:issuetracker.google.com/35905894#comment38
【解决方案2】:

现在所有 BigQuery 用户都可以公开了解 Avro 逻辑类型。请参阅此处的文档页面以获取更多详细信息:https://cloud.google.com/bigquery/docs/loading-data-cloud-storage-avro#logical_types

【讨论】:

  • 更新:BigQuery 现在支持逻辑类型。请参考下面的 Victors 答案。
【解决方案3】:

我在 PostgreSQL 表中有一个带有 TIMESTAMP 列的数据。在遵循 cmets 中 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

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

然后我created a schema file for my data in JSON 在那里我给出了“时间戳”的列类型。

[ {"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 的问题。

【讨论】:

    【解决方案4】:

    我们遇到了同样的问题并解决了。下面是用于将日期数据导入到 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 库创建的测试文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-15
      • 1970-01-01
      • 2018-05-22
      • 1970-01-01
      • 2021-08-18
      • 1970-01-01
      • 2021-05-10
      • 1970-01-01
      相关资源
      最近更新 更多