和impala_Impala和parquet的一个大坑

事情起因:一个底层表,存储格式为parquet。该表有一列为status,该列的注释需要修改,但是修改的时候误操作把字段类型由int改成了string。hive查询是没有问题的,但是impala同步元数据后,查询历史分区数据时,会报如下错误

acf8577f0e6cdeace81af6a30dc8e677.png

问题难点:

  1. 由于hive的限制,无法将该列由string改为int

  2. 由于规范性原因,新增字段再删掉这一列,可能会对下游有使用该表且为select * from xx 的有影响

  3. 该表为ods层表,无法通过上游数据重新导入

  4. 历史分区数据还有用,因此不能只保留最新的分区

有一种解决方案是在每一个impala的会话窗口设置参数,使impala可以将元数据和数据映射上,但我试了结果还是一样的。

先说下解决方案:

  1. 要创建一个临时表,status列的字段可以是int,也可以是string。看自己的业务需要是什么。出于对下游可能用到该列考虑,还是将该列设为int。

  2. 将数据插入到临时表中,对该字段类型做cast强转

  3. 删除原表

  4. 将临时表的表名改为原表

这个解决方案说到底并不是真的对字段做了操作,而是通过替换表来做的。整体的代码很简单,放一个字段类型为string的。思路都是一样的。

---复现问题ALTER table db.table_name change column status status string;--尝试修复1:创建临时表,status字段为stringCREATE table db.table_name_tmp like db.table_name;insert overwrite table db.table_name_tmp partition(dt)select id, cast(status as string), createtimefrom db.table_name;drop table if exists  db.table_name;alter table  db.table_name_tmp rename to  db.table_name;

问题原因待整理,如果有更好的解决方法,欢迎留言~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值