1 問題場景
假設(shè)某有數(shù)據(jù)的Hive表temp_table的字段狀況如下,需要將A字段由string類型轉(zhuǎn)為int類型:
字段名稱 | 字段類型 | 是否為分區(qū)字段 |
---|---|---|
A | string | 否 |
B | int | 否 |
C | bigint | 否 |
D | string | 是 |
1.1 問題發(fā)生的背景
在Hdfs數(shù)據(jù)庫中,該表的數(shù)據(jù)是以Parquet文件格式存儲的,包含多個分區(qū)。原本在該表中的字段A的類型為int。然而筆者誤操作,將該字段的類型轉(zhuǎn)換為了string,即前文所述的表字段狀態(tài)。
筆者在查詢時發(fā)現(xiàn),用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元數(shù)據(jù)中的字段類型不同,且無法強制轉(zhuǎn)換。
為了繼續(xù)可以用spark查詢本表,筆者嘗試修復表字段類型。然而在修復表字段類型時,筆者發(fā)現(xiàn)以下兩種方法都無法完成操作,并且會報錯:
1.1 操作方法1
使用如下語句修改Hive表的字段類型時??赡軙l(fā)現(xiàn)字段可以從string轉(zhuǎn)到Int,但不能從Int轉(zhuǎn)回String。
ALTER TABLE temp_table CHANGE CLOUMN A A int;
1.2 操作方法2
- 刪除要轉(zhuǎn)換類型的字段A,使原表只剩B、C兩個字段。
- 新增字段A,將類型轉(zhuǎn)換為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表元數(shù)據(jù)中已有的字段類型無法被轉(zhuǎn)換為新指定的字段類型。而且結(jié)合上述操作方法2可知,如果表中有數(shù)據(jù),那么即便刪除了某個字段,其字段類型仍然會保留在原來的位置上。
2 問題分析
查看官方文檔后,可以了解到,列轉(zhuǎn)換操作是由一個參數(shù)控制的:
當 hive.metastore.disallow.incompatible.col.type.changes 設(shè)置為 false 時,Metastore 中的列類型可以從任何類型更改為任何其他類型。 在執(zhí)行類型更改后,如果新類型可以正確顯示數(shù)據(jù),則將顯示數(shù)據(jù)。 否則,數(shù)據(jù)將顯示為 NULL。
而hive.metastore.disallow.incompatible.col.type.changes這個參數(shù),在Hive2.0后,默認為True。即在字段類型轉(zhuǎn)換時,不再允許顯式轉(zhuǎn)換(強制轉(zhuǎn)換),而是只能進行隱式轉(zhuǎn)換,即由低級類型轉(zhuǎn)換為高級類型。
關(guān)于隱式轉(zhuǎn)換的規(guī)則,Hive官方文檔(需要翻墻后查看該鏈接)中的說明如下:
本例中的Hive版本為2.7.2
所以為了實現(xiàn)字段類型的顯式轉(zhuǎn)換,需要設(shè)置hive.metastore.disallow.incompatible.col.type.changes。
3 解決方法
特別注意:在某些環(huán)境下,前兩種方法都不能使該參數(shù)生效,只能使用第三種方法
3.1 在SQL代碼中加參數(shù)
在SQL代碼最前方加入:set hive.metastore.disallow.incompatible.col.type.changes=false;
3.2 在提交Hive程序時,附加上hiveconf參數(shù)
3.3 修改 hive-site.xml文件
在hive 配置文件 hive-site.xml中添加或修改參數(shù):文章來源:http://www.zghlxwxcb.cn/news/detail-431916.html
<property>
<name>hive.metastore.disallow.incompatible.col.type.changes</name>
<value>false</value>
</property>
修改參數(shù)之后,需要重啟Hive服務才能使參數(shù)生效。重啟Hive服務后,使用Hive查詢該參數(shù)值,可以發(fā)現(xiàn)修改成功了
同時,可以在DDL語句修改Hive元數(shù)據(jù)中的字段類型時,實現(xiàn)顯式轉(zhuǎn)換。文章來源地址http://www.zghlxwxcb.cn/news/detail-431916.html
到了這里,關(guān)于Hive表字段類型轉(zhuǎn)換錯誤解決:Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask.的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!