irpas技术客

Hive表字段类型转换错误解决:Execution Error, return code 1 from org.apache.hadoop.hive.ql.ex

网络投稿 4002

文章目录 1 问题场景1.1 问题发生的背景1.1 操作方法11.2 操作方法21.3 报错信息 2 问题分析3 解决方法3.1 在SQL代码中加参数3.2 在提交Hive程序时,附加上hiveconf参数3.3 修改 hive-site.xml文件

1 问题场景

假设某有数据的Hive表temp_table的字段状况如下,需要将A字段由string类型转为int类型:

字段名称字段类型是否为分区字段Astring否Bint否Cbigint否Dstring是
1.1 问题发生的背景

在Hdfs数据库中,该表的数据是以Parquet文件格式存储的,包含多个分区。原本在该表中的字段A的类型为int。然而笔者误操作,将该字段的类型转换为了string,即前文所述的表字段状态。

笔者在查询时发现,用HiveSql查询不会报错,而用SparkSql查询本表时,会报如下错误信息:

org.apache.spark.sql.execution.QueryExecutionException: Parquet column cannot be converted in file [文件所在OSS路径]. Column: [has_explicit_source_keys], Expected: StringType, Found: INT32

错误的大致意思为文件中的字段类型和Hive元数据中的字段类型不同,且无法强制转换。 为了继续可以用spark查询本表,笔者尝试修复表字段类型。然而在修复表字段类型时,笔者发现以下两种方法都无法完成操作,并且会报错:

1.1 操作方法1

使用如下语句修改Hive表的字段类型时。可能会发现字段可以从string转到Int,但不能从Int转回String。

ALTER TABLE temp_table CHANGE CLOUMN A A int; 1.2 操作方法2 删除要转换类型的字段A,使原表只剩B、C两个字段。新增字段A,将类型转换为int。由于Hive建表时不允许指定列的位置,所以会添加在表的最后。将字段A挪到第一位。本步会报错,不允许进行此操作。 -- Step1 ALTER TABLE temp_table replace COLUMNS (B int,C bigint); -- Step2 ALTER TABLE temp_table ADD COLUMNS (A int); -- Step3(本步会报错) ALTER TABLE temp_table CHANGE CLOUMN A A int FIRST; 1.3 报错信息 FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Unable to alter table. The following columns have types incompatible with the existing columns in their respective positions : column_name

该错误的意思是,Hive表元数据中已有的字段类型无法被转换为新指定的字段类型。而且结合上述操作方法2可知,如果表中有数据,那么即便删除了某个字段,其字段类型仍然会保留在原来的位置上。

2 问题分析

查看官方文档后,可以了解到,列转换操作是由一个参数控制的:

当 hive.metastore.disallow.incompatible.col.type.changes 设置为 false 时,Metastore 中的列类型可以从任何类型更改为任何其他类型。 在执行类型更改后,如果新类型可以正确显示数据,则将显示数据。 否则,数据将显示为 NULL。

而hive.metastore.disallow.incompatible.col.type.changes这个参数,在Hive2.0后,默认为True。即在字段类型转换时,不再允许显式转换(强制转换),而是只能进行隐式转换,即由低级类型转换为高级类型。

关于隐式转换的规则,Hive官方文档(需要翻墙后查看该链接)中的说明如下: 本例中的Hive版本为2.7.2

所以为了实现字段类型的显式转换,需要设置hive.metastore.disallow.incompatible.col.type.changes。

3 解决方法

特别注意:在某些环境下,前两种方法都不能使该参数生效,只能使用第三种方法

3.1 在SQL代码中加参数

在SQL代码最前方加入:set hive.metastore.disallow.incompatible.col.type.changes=false;

3.2 在提交Hive程序时,附加上hiveconf参数 3.3 修改 hive-site.xml文件

在hive 配置文件 hive-site.xml中添加或修改参数:

<property> <name>hive.metastore.disallow.incompatible.col.type.changes</name> <value>false</value> </property>

修改参数之后,需要重启Hive服务才能使参数生效。重启Hive服务后,使用Hive查询该参数值,可以发现修改成功了 同时,可以在DDL语句修改Hive元数据中的字段类型时,实现显式转换。


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #hive修改字段类型后查询报错 #Execution #error #return #code #1