【发布时间】:2017-10-31 23:15:45
【问题描述】:
Spark 解释 parquet 列的方式存在一些问题。
我有一个确认架构的 Oracle 源代码(df.schema() 方法):
root
|-- LM_PERSON_ID: decimal(15,0) (nullable = true)
|-- LM_BIRTHDATE: timestamp (nullable = true)
|-- LM_COMM_METHOD: string (nullable = true)
|-- LM_SOURCE_IND: string (nullable = true)
|-- DATASET_ID: decimal(38,0) (nullable = true)
|-- RECORD_ID: decimal(38,0) (nullable = true)
然后将其保存为 Parquet - df.write().parquet() 方法 - 具有相应的消息类型(由 Spark 确定):
message spark_schema {
optional int64 LM_PERSON_ID (DECIMAL(15,0));
optional int96 LM_BIRTHDATE;
optional binary LM_COMM_METHOD (UTF8);
optional binary LM_SOURCE_IND (UTF8);
optional fixed_len_byte_array(16) DATASET_ID (DECIMAL(38,0));
optional fixed_len_byte_array(16) RECORD_ID (DECIMAL(38,0));
}
然后我的应用程序使用 HashMap 生成表 DDL 进行类型转换,例如:
CREATE EXTERNAL TABLE IF NOT EXISTS
ELM_PS_LM_PERSON (
LM_PERSON_ID DECIMAL(15,0)
,LM_BIRTHDATE TIMESTAMP
,LM_COMM_METHOD STRING
,LM_SOURCE_IND STRING
,DATASET_ID DECIMAL(38,0)
,RECORD_ID DECIMAL(38,0)
) PARTITIONED BY (edi_business_day STRING) STORED AS PARQUET LOCATION '<PATH>'
我的问题是 Impala 无法读取该表,因为它不接受 LM_PERSON_ID 作为十进制字段。如果此列设置为 BIGINT,该表将仅读取 parquet 文件。
Query 8d437faf6323f0bb:b7ba295d028c8fbe: 0% Complete (0 out of 1)
File 'hdfs:dev/ELM/ELM_PS_LM_PERSON/part-00000-fcdbd3a5-9c93-490e-a124-c2a327a17a17.snappy.parquet' has an incompatible Parquet schema for column 'rbdshid1.elm_ps_lm_person_2.lm_person_id'.
Column type: DOUBLE, Parquet schema:
optional int64 LM_PERSON_ID [i:0 d:1 r:0]
我如何知道何时将小数字段替换为 BIGINT?
parquet 消息类型已记录但无法访问?
两个十进制字段转换为fixed_len_byte_array(16),LM_PERSON_ID转换为int64
我能想到的唯一解决方案是创建表,测试它是否返回,如果不删除并将十进制字段一一替换为 BIGINT,每次测试。
我在这里缺少什么?我可以为 parquet 文件强制执行十进制模式吗?
【问题讨论】:
标签: java apache-spark apache-spark-sql parquet