apache-spark - Spark编写Parquet数组加载到 BigQuery 时转换为不同的数据类型
问题描述
Spark 数据框架构:
StructType(
[StructField("a", StringType(), False),
StructField("b", StringType(), True),
StructField("c" , BinaryType(), False),
StructField("d", ArrayType(StringType(), False), True),
StructField("e", TimestampType(), True)
])
当我将数据框写入 parquet 并将其加载到 BigQuery 时,它会以不同的方式解释架构。这是一个简单的 JSON 加载,并使用 spark 数据框写入 parquet。
BigQuery 架构:
[
{
"type": "STRING",
"name": "a",
"mode": "REQUIRED"
},
{
"type": "STRING",
"name": "b",
"mode": "NULLABLE"
},
{
"type": "BYTES",
"name": "c",
"mode": "REQUIRED"
},
{
"fields": [
{
"fields": [
{
"type": "STRING",
"name": "element",
"mode": "NULLABLE"
}
],
"type": "RECORD",
"name": "list",
"mode": "REPEATED"
}
],
"type": "RECORD",
"name": "d",
"mode": "NULLABLE"
},
{
"type": "TIMESTAMP",
"name": "e",
"mode": "NULLABLE"
}
]
这与 Spark 的写入方式或 BigQuery 读取镶木地板的方式有关吗?知道如何解决这个问题吗?
解决方案
这是由于spark-bigquery 连接器使用的中间文件格式(默认情况下为 parquet)。
连接器首先将数据写入 parquet 文件,然后使用 BigQuery Insert API 将它们加载到 BigQuery。
如果您使用 来检查中间镶木地板模式parquet-tools
,您会发现类似这样的字段d
(Spark 中的 ArrayType(StringType))
optional group a (LIST) {
repeated group list {
optional binary element (STRING);
}
}
现在,如果您自己在 BigQuery 中使用bq load
或直接使用 BigQuery Insert API 加载此镶木地板,您可以通过启用来告诉 BQ 忽略中间字段parquet_enable_list_inference
不幸的是,在使用 spark-bigquery 连接器时,我看不到如何启用此选项!
作为一种解决方法,您可以尝试将其orc
用作中间格式。
df
.write
.format("bigquery")
.option("intermediateFormat", "orc")
推荐阅读
- python - 如何将 for 循环合并到此函数中并且仍然具有相同的结果?
- python - 如何使用 scapy PcapWriter 对数据包强制校验和错误?
- javascript - 在 Discord 上的服务器中发送关于 guildMemberAdd 事件的消息
- go - 通过 SSH 流式传输 Stdout 和 Stderr,操作流,然后打印到本地 Stdout 和 Stderr
- google-api - 如何使用方法事件:使用google-calendar-api获取具有指定创建时间或更新时间的事件?
- mysql - MYSQL 查询不返回 BETWEEN 的结果,但它返回小于和等于子查询的结果
- java - Double 无法取消引用,解析二维数组
- c++ - 对齐究竟如何影响内存布局和放置新的行为?
- git - `reflog` 是否维护被创建、移动、操作、合并或删除的分支名称的历史记录?
- angular - 角垫表消除波纹