1 问题场景
假设某有数据的Hive表temp_table的字段状况如下,需要将A字段由string类型转为int类型:
字段名称 | 字段类型 | 是否为分区字段 |
---|---|---|
A | string | 否 |
B | int | 否 |
C | bigint | 否 |
D | string | 是 |
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中添加或修改参数:文章来源:https://www.toymoban.com/news/detail-431916.html
<property>
<name>hive.metastore.disallow.incompatible.col.type.changes</name>
<value>false</value>
</property>
修改参数之后,需要重启Hive服务才能使参数生效。重启Hive服务后,使用Hive查询该参数值,可以发现修改成功了
同时,可以在DDL语句修改Hive元数据中的字段类型时,实现显式转换。文章来源地址https://www.toymoban.com/news/detail-431916.html
到了这里,关于Hive表字段类型转换错误解决:Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask.的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!