我从hive表中读取spark数据框时遇到了麻烦。我将数据帧存储为:
dataframe.coalesce(n_files).write.option("mergeSchema", "true").mode("overwrite").parquet(table_path)
当我尝试读取此数据框并对其进行.show()
时,它会出现以下错误:
java.lang.UnsupportedOperationException: parquet.column.values.dictionary.PlainValuesDictionary$PlainIntegerDictionary
at parquet.column.Dictionary.decodeToLong(Dictionary.java:52)
我如何找到哪一列是这个错误的根本原因?我试着跟着答案走。但是我能够很好地加载df,读取parquet文件:
df = spark.read.option("mergeSchema", "True").parquet("/hdfs path to parquets")
- 上述hive表是一个外部表。我猜它与表属性有关?但我该看什么呢?
- 我不能使用
saveAsTable
。由于某些要求,我需要直接写入路径
找到了问题的根本原因。把我的发现贴在这里,这样有需要的人就可以看看他们的情况是否相同。
我遇到这个问题是因为hive表元数据和parquets中的数据类型不同。事情是当你做一个saveAsTable
火花将类型转换你的数据,同时保存,如果有任何差异。但是当您执行df.write.parquet(path)
时,您将直接将您的parquets写入路径,因此如果表元数据和parquets之间存在不匹配,df.show
将抛出错误。
例如,如果您的表元数据为列A具有dtype'bigint'
,但您试图保存的df为同一列具有dtypeIntegerType
(而不是LongType
,这是bigint
的正确解释),则saveAsTable
会将IntegerType
类型转换为LongType
,但df.write.parquet(path)
不会。
解决方案是将有问题的列类型转换为与表元数据匹配的dtype。