ApacheSpark:不支持的镶木地板数据类型

时间:2015-08-05 06:32:18

标签: scala apache-spark hive cloudera apache-spark-sql

我试图用SparkSql HiveContext读取Hive表。但是,当我提交作业时,我收到以下错误:

wget

列类型为DECIMAL(24,7)。我已经使用HiveQL更改了列类型,但它不起作用。此外,我已尝试在sparksql中转换为另一个Decimal类型,如下所示:

Exception in thread "main" java.lang.RuntimeException: Unsupported parquet datatype optional fixed_len_byte_array(11) amount (DECIMAL(24,7))
            at scala.sys.package$.error(package.scala:27)
            at org.apache.spark.sql.parquet.ParquetTypesConverter$.toPrimitiveDataType(ParquetTypes.scala:77)
            at org.apache.spark.sql.parquet.ParquetTypesConverter$.toDataType(ParquetTypes.scala:131)
            at org.apache.spark.sql.parquet.ParquetTypesConverter$$anonfun$convertToAttributes$1.apply(ParquetTypes.scala:383)
            at org.apache.spark.sql.parquet.ParquetTypesConverter$$anonfun$convertToAttributes$1.apply(ParquetTypes.scala:380)

但是,我得到了同样的错误。我的代码是这样的:

val results = hiveContext.sql("SELECT cast(amount as DECIMAL(18,7)), number FROM dmp_wr.test")

我该如何解决这个问题?感谢您的回复。

Edit1 :我发现抛出异常的Spark源代码行。它看起来像那样

def main(args: Array[String]) {
val conf: SparkConf = new SparkConf().setAppName("TColumnModify")
val sc: SparkContext = new SparkContext(conf)
val vectorAcc = sc.accumulator(new MyVector())(VectorAccumulator)
val hiveContext = new org.apache.spark.sql.hive.HiveContext(sc)
val results = hiveContext.sql("SELECT amount, number FROM dmp_wr.test")

所以,我创建了一个新表,其中包含DECIMAL(18,7)类型的列,我的代码按预期工作。 我删除表并创建一个在DECIMAL(24,7)中有列的新表,之后我更改了列类型 if(originalType == ParquetOriginalType.DECIMAL && decimalInfo.getPrecision <= 18) 我可以看到它被改为DECIMAL(18,7),但是Spark 不接受改变。它仍然将列类型读为DECIMAL(24,7)并给出相同的错误。 可能是什么主要原因?

1 个答案:

答案 0 :(得分:2)

alter table qwe change amount amount decimal(18,7)

Hive中的更改表命令不会触及存储在Hive中的实际数据。它只会更改Hive Metastore中的元数据。这与普通数据库(如MySQL)中的“alter table”命令非常不同。

当Spark从Parquet文件中读取数据时,它会尝试使用实际Parquet文件中的元数据 来反序列化数据,这仍然会给它DECIMAL(24,7)。

您的问题有两种解决方案: 1.尝试新版本的Spark - 从trunk创建。请参阅https://issues.apache.org/jira/browse/SPARK-6777,它完全改变了这部分代码(虽然只会在Spark 1.5中),所以希望你不会再看到同样的问题。

  1. 手动转换表格中的数据。您可以使用像“INSERT OVERWRITE TABLE new_table SELECT * from old_table”这样的配置单元查询来执行此操作。