通过 CLI 将存储桶中的 AVRO 加载到具有日期分区的 BigQuery 中

Posted

技术标签:

【中文标题】通过 CLI 将存储桶中的 AVRO 加载到具有日期分区的 BigQuery 中【英文标题】:Loading AVRO from Bucket via CLI into BigQuery with Date partition 【发布时间】:2020-04-21 12:59:56 【问题描述】:

我正在尝试通过带有日期分区的 AVRO 将数据导入 BigQuery。通过 cli 导入时,与分区日期相关的错误必须是 Date 或 Timestamp 但它正在获取 Integer。

给定一个类似于以下的 AVRO 文件:


  "namespace": "test_namespace",
  "name": "test_name",
  "type": "record",
  "fields": [
     
      "name": "partition_date",
      "type": "int",
      "logicalType": "date"
    ,
    
      "name": "unique_id",
      "type": "string"
    ,
    
      "name": "value",
      "type": "double"
    

然后我通过 CLI 使用以下命令来尝试创建一个新表

bg load \
--replace \
--source_format=AVRO \
--use_avro_logical_types=True \
--time_partitioning_field partition_date \
--clustering_fields unique_id \
mydataset.mytable \
gs://mybucket/mydata.avro

期望一个新表在日期列“partition_date”上进行分区,然后按“unique_id”进行聚类。

编辑:请看下面的错误

The field specified for the time partition can only be of type TIMESTAMP or DATE. The type found is: INTEGER.

我使用的具体命令如下:

bq load --replace --source_format=AVRO --use_avro_logical_types=True --time_partitioning_field "partition_date" --clustering_fields "unique_id" BQ_DATASET BUCKET_URI

这是我正在使用的 AVRO 架构


    "namespace": "example.avro",
    "type": "record",
    "name": "Test",
    "fields": [
         "name": "partition_date", "type": "int", "logicalType": "date" ,
         "name": "unique_id", "type": "string",
         "name": "value", "type": "float" 
   ]

值得注意的是,这是一个旧的 Google 项目(大约 2 到 3 年的历史),如果有任何相关性的话。

我也在使用最新的 Google SDK 的 Windows 10。

【问题讨论】:

【参考方案1】:

Google 终于回复了我(7 个月后)。在这段时间里,我不再能够访问我遇到问题的初始项目。不过,我正在为那些后来在新项目中发现这一点的人记录一个成功的例子。

根据问题跟踪器here 的评论,我发现我没有为逻辑日期字段使用复杂类型。

所以这个:

 
  "name": "partition_date",
  "type": "int",
  "logicalType": "date"

应该这样写(注意类型的嵌套复杂对象):

 
  "name": "partition_date",
  "type": 
    "type": "int",
    "logicalType": "date"
  

虽然avro specification 列出了一个日期作为从 unix 时代(1970 年 1 月 1 日)开始的天数,但我不得不将 partition_date 写为datetime.date(1970, 1, 1) 而不仅仅是0

命令(bq)与原始帖子没有变化。

如上所述,我不知道这是否能解决我在原始项目中的问题,但希望这可以帮助下一个人。

【讨论】:

非常感谢您分享这个@michaelgambod。它为我节省了大量时间。【参考方案2】:

在执行相同的加载操作、生成相同的 AVRO 数据架构并使用所需的 Bigdata 接收器表结构时,我没有收到任何错误消息。

根据 GCP documentation,您已在 bq 命令行中使用 --use_avro_logical_types=True 标志正确传播 conversion 数据类型,保持 DATA Avro 逻辑类型在 Bigquery 中被转换为等效的 Date 类型.

您可以参考我的 Bigquery 表架构,在您这边验证表结构,因为您没有提供表结构和错误消息本身,到目前为止我无法提供更多建议:

$ bq show --project_id=<Project_ID>  <Dataset>.<Table>
Table <Project_ID>:<Dataset>.<Table>

   Last modified            Schema            Total Rows   Total Bytes   Expiration        Time Partitioning        Clustered Fields   Labels
 ----------------- ------------------------- ------------ ------------- ------------ ----------------------------- ------------------ --------
  22 Apr 12:03:57   |- partition_date: date   3            66                         DAY (field: partition_date)   unique_id
                    |- unique_id: string
                    |- value: float

我使用FLOAT 类型为value 来根据建议here 明确转换AVRO DOUBLE 数据类型。

bqCLI 版本:

$ bq version
This is BigQuery CLI 2.0.56

您可以随意扩展原始问题,提供有关您遇到的问题的更具体信息,进一步帮助更准确地解决问题。

更新:

我已经检查了提供的信息,但我仍然对您遇到的错误感到困惑。显然,我看到在您的情况下,标志 use_avro_logical_types=True 不执行逻辑类型转换。但是我发现了这个 PIT 功能request,人们要求将他们的项目“列入白名单”以提供 AVRO 逻辑类型功能,即这个comment。由于此功能已在全球社区推出,可能是某些 GCP 项目无法使用它的疏忽。

【讨论】:

我已经为我的答案写了一些注释,请检查它们。 谢谢你,当事情不按照文档工作时,这令人沮丧(尽管谷歌的文档非常......简短)。我试图查看您发送的链接,但无法使用我的 Google 凭据登录。它把我带到了一个谷歌公司登录,上面有“谷歌里面的妈妈” 我替换了错误的链接,很抱歉,请检查一下。 您也可以考虑在单独的PIT 线程中提出个人问题。随时在这里分享任何进一步的灵感。 如果您觉得我的回答有帮助,请考虑 accept/up 投票给我的回答,让下一位贡献者有机会在相关主题的研究中获得支持。

以上是关于通过 CLI 将存储桶中的 AVRO 加载到具有日期分区的 BigQuery 中的主要内容,如果未能解决你的问题,请参考以下文章

将 Avro 中存储为整数(自 1970 年 1 月 1 日以来的天数)的“日期”转换为雪花“日期”类型

如何将 Avro 文件加载到具有“时间戳”类型的列的 BigQuery 表中

如何从具有 DATE 列的 BigQuery 表中导出 AVRO 文件并将其再次加载到 BigQuery

从 HIVE 表加载到 HDFS 作为 AVRO 文件

S3 存储桶中的视频不会在页面加载时打开

如何从 S3 存储桶中读取最后修改的 csv 文件?