镶木地板数据类型问题

时间:2018-05-17 04:29:50

标签: scala apache-spark apache-spark-sql parquet

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

但是当我发出

select * from my_table

它返回了

  

错误:文件' hdfs://xyz..'列#xyz'具有不兼容的Parquet架构。列类型:DECIMAL(5,2),Parquet架构:可选int32 final_apr [i:4 d:1 r:0]。

所以我仔细查看了命令的输出

parquet-tools schema my_parquet

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

所以我手动执行了命令

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;

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

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

有没有更好的方法来处理这个问题,而不是手动更新列来更改所有INT64非固定长度字节数组的数据类型?可能就像在读取镶木地板文件作为Dataframe之后,找出所有INT64非固定长度字节数组列将它们转换为BIGINT然后将数据帧保存为表格?

是的,即使在更改了列的数据类型之后,我也无法在hive shell中执行select * from my_from;查询。我收到错误信息

  

错误:编译语句时出错:FAILED:ParseException line 1:30 extraneous input' limit'期待数字接近'' (状态= 42000,代码= 40000)。

我试过几个表,所有这些表都与hive shell有同样的问题。

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

Parquet架构的警告int32意味着你的impala列类型应该是int而不是bigint。当您将table列更改为int时,它应该可以工作。 Btw,spark和impala镶木地板读取方法不同。 Impala遵循更保守的方式来阅读镶木地板文件。例如;当impala执行时,sp​​ark不会控制不同列索引中的值的数量。

答案 1 :(得分:0)

我在将镶木地板数据从 s3 复制到带有十进制列的红移时遇到了类似的问题。我得到了

  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

红移中的列是 DECIMAL(9,5)。镶木地板中的列是 double。我无法更改数据库,因为生产。我最终像这样修改了镶木地板输出:

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