关于scala:Parquet数据类型问题

Parquet Datatype Issue

我有一堆镶木地板文件,并且已经使用Impala的CREATE EXTERNAL TABLE...创建了外部表。

但是当我发布

1
select * from my_table

它返回了

ERROR: File 'hdfs://xyz..' has an incompatible Parquet schema for column 'xyz'. Column type: DECIMAL(5, 2), Parquet schema:optional int32 final_apr [i:4 d:1 r:0].

所以我仔细查看了命令

的输出

1
parquet-tools schema my_parquet

并观察到所有INT64而不是fixed_len_byte_array的列都存在此问题。

所以我手动执行了命令

1
ALTER TABLE schema.table_name CHANGE old-column new_column BIGINT;

可以根据https://www.cloudera.com/documentation/enterprise/5-6-x/topics/impala_parquet.html将默认创建的列类型更改为BIGINT,那么我能够执行select * from my_table;

我已经在Scala中使用spark练习了上述内容,即我能够读取镶木地板文件并将其存储为impala表,还能够以编程方式发出" select * from my_table"查询。

但是我尝试从impala shell手动查询,但是遇到了上面显示的相同错误。

不是手动更新列以更改所有INT64非固定长度字节数组的数据类型,有没有更好的方法来处理此问题?可能类似于将镶木地板文件读取为Dataframe之后,找出所有INT64非固定长度字节数组列将其转换为BIGINT,然后将数据帧另存为表格吗?

顺便说一句,即使更改了列的数据类型,我也无法在配置单元shell中执行select * from my_from;查询。我收到错误消息味精

Error: Error while compiling statement: FAILED: ParseException line 1:30 extraneous input 'limit' expecting Number near '' (state=42000,code=40000).

我尝试了几个表,它们都与hive壳有相同的问题。

感谢您的帮助!


Parquet模式的警告int32意味着您的impala列类型应为int而不是bigint。当您将表列更改为int时,它应该可以工作。
顺便说一句,spark和impala实木复合地板的读取方法是不同的。 Impala遵循一种更为保守的方式来读取实木复合地板文件。例如;当impala进行操作时,spark不能控制不同列索引中的值数量。


我遇到了类似的问题,将镶木地板数据从s3复制到带小数点列的redshift。我正在得到

1
2
3
4
  code:      15001
  context:   File 'https://s3.us-east-1.amazonaws.com/bucket/filename.snappy.parquet  
             has an incompatible Parquet schema for column
             '
s3://bucket/filename/.column_name'. Column type: DECIMAL(9

redshift中的列为DECIMAL(9,5)。实木复合地板中的列为double。由于生产,我无法更改数据库。我最终修改了镶木地板的输出,如下所示:

1
2
val nineFive =  DataTypes.createDecimalType(9,5)
val df2 = df.withColumn("column_name", $"column_name" cast nineFive)