【发布时间】:2018-10-19 00:53:04
【问题描述】:
我正在尝试将 Parquet 数据加载到 Google BigQuery 中,以利用高效的列格式并(我希望)解决 BigQuery 对 AVRO 文件中的逻辑类型(DATE 等)缺乏支持的问题。
我的数据包含两层嵌套数组。
使用 JSON,我可以创建并加载具有所需结构的表:
bq mk temp.simple_interval simple_interval_bigquery_schema.json
bq load --source_format=NEWLINE_DELIMITED_JSON temp.simple_interval ~/Desktop/simple_interval.json
bq show temp.simple_interval
Last modified Schema Total Rows Total Bytes Expiration Time Partitioning Labels
----------------- ---------------------------------------- ------------ ------------- ------------ ------------------- --------
09 May 13:21:56 |- file_name: string (required) 3 246
|- file_created: timestamp (required)
|- id: string (required)
|- interval_length: integer (required)
+- days: record (repeated)
| |- interval_date: date (required)
| |- quality: string (required)
| +- values: record (repeated)
| | |- interval: integer (required)
| | |- value: float (required)
我尝试使用 AvroParquetWriter 创建与 Parquet 数据文件相同的结构。我的 AVRO 架构是:
{
"name": "simple_interval",
"type": "record",
"fields": [
{"name": "file_name", "type": "string"},
{"name": "file_created", "type": {"type": "long", "logicalType": "timestamp-millis"}},
{"name": "id", "type": "string"},
{"name": "interval_length", "type": "int"},
{"name": "days", "type": {
"type": "array",
"items": {
"name": "days_record",
"type": "record",
"fields": [
{"name": "interval_date", "type": {"type": "int", "logicalType": "date"}},
{"name": "quality", "type": "string"},
{"name": "values", "type": {
"type": "array",
"items": {
"name": "values_record",
"type": "record",
"fields": [
{"name": "interval", "type": "int"},
{"name": "value", "type": "float"}
]
}
}}
]
}
}}
]
}
从 AVRO 规范和我在网上找到的内容来看,似乎有必要以这种方式将 'record' 节点嵌套在 'array' 节点中。
当我创建 Parquet 文件时,Parquet 工具将架构报告为:
message simple_interval {
required binary file_name (UTF8);
required int64 file_created (TIMESTAMP_MILLIS);
required binary id (UTF8);
required int32 interval_length;
required group days (LIST) {
repeated group array {
required int32 interval_date (DATE);
required binary quality (UTF8);
required group values (LIST) {
repeated group array {
required int32 interval;
required float value;
}
}
}
}
}
我将文件加载到 BigQuery 并检查结果:
bq load --source_format=PARQUET temp.simple_interval ~/Desktop/simple_interval.parquet
bq show temp.simple_interval
Last modified Schema Total Rows Total Bytes Expiration Time Partitioning Labels
----------------- --------------------------------------------- ------------ ------------- ------------ ------------------- --------
09 May 13:05:54 |- file_name: string (required) 3 246
|- file_created: timestamp (required)
|- id: string (required)
|- interval_length: integer (required)
+- days: record (required)
| +- array: record (repeated) <-- extra column
| | |- interval_date: date (required)
| | |- quality: string (required)
| | +- values: record (required)
| | | +- array: record (repeated) <-- extra column
| | | | |- interval: integer (required)
| | | | |- value: float (required)
这是可行的,但我想知道,有没有办法避免额外的“数组”中间节点/列?
我错过了什么吗?对于嵌套数组,AVRO/Parquet 有没有办法像 JSON 一样获得更简单的 BigQuery 表结构?
【问题讨论】:
-
不知道 Parquet,但 BQ 将很快支持 Avro 中的 FYI 逻辑类型,issuetracker.google.com/issues/35905894。
-
感谢有关 Avro 逻辑类型的指针。我很期待。但是,鉴于 Parquet 的柱状性质,它似乎更适合 BigQuery。对于我生成的简单测试数据(列中有很多重复,这是我的数据的典型特征),Avro 的大小约为 JSON 的 25%,而 Parquet 的大小不到 JSON 的 1%!
-
我注意到关于这个问题的另一个事实,这似乎表明它是 Parquet 特有的,或者可能是 AvroParquetWriter 特有的。当我使用此 Avro 方案编写 Avro 文件时,如果我使用 Avro 工具将其序列化为 JSON,我会得到我想要的简单 JSON(没有“数组”节点)。当我使用 AvroParquetWriter 和相同的 Avro 模式编写 Parquet 文件并使用 Parquet 工具序列化回 JSON 时,我得到了这些额外的“数组”节点。也许 AvroParquetWriter 中有一些选项可以控制它。我会调查的。
-
如果你能解决你的问题,你能发布一个答案并接受它吗?
标签: google-bigquery avro parquet