Presto中int列转double是否合法?修改后查询报错如何解决?
问题背景
用ALTER语句修改Hive表中int类型的col1为double类型:
ALTER TABLE schema_name.table_name CHANGE COLUMN col1 col1 double CASCADE;
在Hive中查询该表分区partition_column = '2022-12-01'正常,但Presto执行查询:
select * from schema_name.table_name where partition_column = '2022-12-01'
时报错:
schema_name.table_name is declared as type double, but the Parquet file (hdfs://ns-platinum-prod-phx/secure/user/hive/warehouse/db_name.db/table_name/partition_column=2022-12-01/000002_0) declares the column as type INT32
根源是ALTER只修改了Hive元数据,HDFS上的Parquet文件里col1还是INT32类型。Hive默认会自动做类型兼容转换,但Presto默认严格校验元数据与文件实际类型,所以触发报错。
可行解决方案(无需全量重写数据)
开启Presto类型兼容配置
在Presto的Hive连接器配置文件(如etc/catalog/hive.properties)中添加:hive.parquet.coerce-types=true hive.allow-type-mismatch=true也可以在会话级别临时生效:
SET SESSION hive.parquet.coerce_types = true; SET SESSION hive.allow_type_mismatch = true;开启后Presto会自动把INT32转为double,不用动原表和数据。
创建视图封装类型转换
基于原表建一个视图,在视图里显式转换col1类型:CREATE VIEW schema_name.table_double_view AS SELECT CAST(col1 AS DOUBLE) AS col1, col2, col3, partition_column -- 替换为表中其他实际字段 FROM schema_name.table_name;之后直接查询这个视图就能拿到正确类型的数据,完全不影响原表。
渐进式更新分区数据
如果要彻底修正文件里的类型,可以分批处理分区,每次只操作一个分区:INSERT OVERWRITE TABLE schema_name.table_name PARTITION(partition_column='2022-12-01') SELECT CAST(col1 AS DOUBLE), col2, col3 -- 其他字段原样保留 FROM schema_name.table_name WHERE partition_column='2022-12-01';这种方式可以分阶段处理,避免一次性操作全量数据带来的资源压力。
内容的提问来源于stack exchange,提问作者Koulick Sadhu

