我试图用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)并给出相同的错误。
可能是什么主要原因?
答案 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中),所以希望你不会再看到同样的问题。