Spark Thrift Server修改嵌套结构体列ALTER TABLE命令失效问题
修改嵌套结构体类型列的ALTER TABLE命令执行失败
问题场景
通过Beeline连接配置了远程Hive Metastore的Spark Thrift Server,执行修改嵌套结构体类型列的ALTER TABLE命令时失败。
创建表语句
CREATE TABLE `test_schema`.`nested_test_pq` (`key1` ARRAY<STRUCT<`a`: STRING, `b`: STRING, `c`: STRING>>) USING parquet
执行的ALTER命令
alter table test_schema.nested_test_pq change key1 key1 array<struct<a:string,b:string,c:string,d:string>>;
报错信息
Error: org.apache.hive.service.cli.HiveSQLException: Error running query: org.apache.spark.sql.AnalysisException: ALTER TABLE CHANGE COLUMN is not supported for changing column 'key1' with type 'ArrayType(StructType(StructField(a,StringType,true), StructField(b,StringType,true), StructField(c,StringType,true)),true)' to 'key1' with type 'ArrayType(StructType(StructField(a,StringType,true), StructField(b,StringType,true), StructField(c,StringType,true), StructField(d,StringType,true)),true)' at org.apache.spark.sql.hive.thriftserver.HiveThriftServerErrors$.runningQueryError(HiveThriftServerErrors.scala:43)
环境版本
- Spark 3.2.1
- Hive Metastore 3.0.0
- Hadoop 3.2.0
已尝试操作
配置hive.metastore.disallow.invalid.col.type.changes为true,无效果。
解决方案
Spark 3.2.x版本中,ALTER TABLE CHANGE COLUMN本身不支持修改嵌套结构体类型(比如给数组内的结构体新增字段),可以用以下几种方案解决:
1. 创建临时表迁移数据(推荐)
这是最安全的方式,步骤如下:
- 新建包含目标字段结构的表:
CREATE TABLE `test_schema`.`nested_test_pq_new` (`key1` ARRAY<STRUCT<`a`: STRING, `b`: STRING, `c`: STRING, `d`: STRING>>) USING parquet - 迁移数据,新增的
d字段可设置默认值(比如空字符串):INSERT INTO `test_schema`.`nested_test_pq_new` SELECT transform(key1, x -> struct(x.a, x.b, x.c, cast('' as string) as d)) as key1 FROM `test_schema`.`nested_test_pq` - 替换原表:
-- 先备份原表 ALTER TABLE `test_schema`.`nested_test_pq` RENAME TO `test_schema`.`nested_test_pq_old`; -- 将新表重命名为原表名 ALTER TABLE `test_schema`.`nested_test_pq_new` RENAME TO `test_schema`.`nested_test_pq`; - 验证数据无误后,可删除旧表:
DROP TABLE `test_schema`.`nested_test_pq_old`;
2. 修改Hive元数据库(谨慎操作)
如果熟悉Hive元数据的数据库结构,可以直接更新元数据中的字段类型定义:
- 找到Hive元数据库中的
COLUMNS_V2表,定位到目标表的key1字段对应的TYPE_NAME值 - 将原类型字符串
array<struct<a:string,b:string,c:string>>修改为array<struct<a:string,b:string,c:string,d:string>> - 注意:这种操作可能导致元数据与实际数据文件不匹配,操作前务必备份元数据,且仅在确认数据兼容的情况下使用。
3. 升级Spark版本
Spark 3.3及以上版本对嵌套类型的ALTER TABLE操作支持有所增强,可以考虑升级到更高版本的Spark来原生支持该需求。
内容的提问来源于stack exchange,提问作者Bill Goldberg
相关产品推荐
相关产品推荐

