hive 修改字段类型_0657-6.2.0-Sqoop导入Parquet文件Hive查询为null问题

作者:余枫

1.问题重现

1.在MySQL中建表,一个bigint字段,二个varchar字段

9e48dfa683a14691877570a53e7b20f2

2.在Hive中建Parquet表

create table test(s1 string comment '字段1',s2 string comment '字段2',s3 string comment '字段3') comment '测试表'stored as parquet;
b46eec9932d94a00bf79bd89fd803b60
de729fe87bb2443bbd04d929203a998c

3.使用Sqoop从MySQL导入数据到HDFS,要导入的目录是Hive中新建表的数据目录

sqoop import --connect jdbc:mysql://192.168.0.178:3306/test --username root --password 123456 --query "select cast(`s1` as char),cast(`s2` as char),cast(`s3` as char) from `test_sqoop` where ( 1=1 ) and $CONDITIONS" --as-parquetfile --append --target-dir /user/hive/warehouse/tsqoop.db/test --m 1
8c706881992f44dba430b87c28e683c8
b1d4ce97864c469e8288d86456f8fbd7

4.查看导入HDFS的文件格式

/opt/cloudera/parcels/CDH/lib/parquet/bin/parquet-tools meta ./5fc2fe2c-10da-4aae-b432-c2b70542bfaf.parquet
6bb5203cdf8548f0816f27b388905bd3

5.数据导入成功后查看Hive表的数据

Hive中查看,查询出的数据为null

c2b46ebf7730476aaa972e0f46c9e0b8

Impala中查看,可以正常查看数据

e8f271625e424d33b443f004aed800da

2.问题分析

在Sqoop抽取MySQL到HDFS的命令中,使用的是query方式,并且语句中使用了cast(s1 as char)的方式,这样查询出来的结果列名产生了变化,不是原来的s1。

f3552010b420451d9ff3dbf6e4622a8f

由上图可见,列名变化了,因此产生的Parquet数据文件中的列名与Hive中建表时定义的列名不同。而在Hive中默认使用名字来查询Parquet的列,所以在Hive中查询出的数据都是null;而在Impala中,则是以位置来查询,所以在Impala中能够正常的查询到数据。

3.问题解决

解决方式有两种,如下:

1.Sqoop命令从MySQL中抽取数据到HDFS时,query语句中指定Hive建表时定义的列名。

·修改Sqoop命令如下,在query中指定Hive表定义的列名

sqoop import --connect jdbc:mysql://192.168.0.178:3306/test --username root --password 123456 --query "select cast(`s1` as char) s1,cast(`s2` as char) s2,cast(`s3` as char) s3 from `test_sqoop` where ( 1=1 ) and $CONDITIONS" --as-parquetfile --append --target-dir /user/hive/warehouse/tsqoop.db/test --m 1
ac31da2750b3490a898ce69b4f1fa338
51cac367dc3a4524aa412d3373f08f4d

·在Hive中进行查询,查询成功

25d88d147bc64dfaa9d119f630a378a0

·在Impala中进行查询,查询成功

3498d527d1b34cd3bd5186ecd48fd9fd

2.在Hive中执行命令set parquet.column.index.access=true;

这个参数的意义是在Hive中以列的序号来访问Parquet数据文件,该参数默认设置为false,即默认是以列名来访问Parquet数据文件。

·在Hive中进行设置

bd891245e2e54a078a5623180a1561e0

·在Hive中进行查询,查询成功

82f5a0bd605f4c8bbac6f3928aae8de6

·在Impala中进行查询,查询成功

427c842832dd45aebfab241f13afeb7e

4.总结

1.使用Sqoop命令进行数据抽取为Parquet格式时,如果导入的数据的列名与Hive建表时定义的列名不一致,会导致Hive中查询到数据为null,因为Hive默认使用列名来访问Parqeut数据文件,可以通过参数set parquet.column.index.access=true来修改访问方式。

2.在Hive和Impala中,默认访问Parquet数据文件的方式不一样,Hive是以列名,Impala是以位置,这一点需要注意。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值