使用sqoop把oracle导入hive 数据列错乱

sqoop1

连接测试Oracle

sqoop-list-databases --connect jdbc:oracle:thin:@192.168.1.**:1521:ORCL --username ** --password ***

将oracle数据导入hive中

sqoop import --connect jdbc:oracle:thin:@192.168.1.**:1521:ORCL --username ** --password *** --table TB_CIS_CONSULT -m 1 --hive-import --hive-database test --hive-table TB_CIS_CONSULT

要注意是 --  不是-


其中端口号后面的ORCL其实是SID,一般SID会与服务名一样,但也要注意。

导入数据错误问题

1.上面命令导入hive的数据会发生错位,甚至多出来很多数据,并产生很多null值,原因是源数据中包含许多’\n’、’\r’、’\01’等字符,表在分割字段和行过程中出现错位;

解决方式:在Sqoop执行中增加属性–hive-drop-import-delims,在导入数据到hive中时,去掉数据中\n,\r和\01这样的字符;

sqoop import —connect jdbc:oracle:thin:@192.168.1.**:1521:ORCL —username **—password ** —table TB_LIS_INDICATORS -m 2 —hive-import —hive-database test —hive-drop-import-delims

2、clob类型字段中保存了json格式数据和xml格式,在导入hive之后,数据被截取成一小段一小段:

原因:clob类型中保存的数据有xml报文和json字符串,包含大量换行符,表在分割字段和行过程中出现错位。

解决方式:在Sqoop执行中增加—map-column-java “SEND_MSG=String,RECV_MSG=String”属性和值

3.问题一:导入的列有换行符等其他字符如何解决

有一张新闻表,其中有一个字段类型为clob,为新闻的内容,里面有各种字符,其中就包括hive中默认的分隔符和自定义的分隔符。这样当导数据到hive中就会造成数据混乱。

网上参考了两个地址:

http://www.th7.cn/Program/java/201608/920584.shtml

http://stackoverflow.com/questions/28076200/hive-drop-import-delims-not-removing-newline-while-using-hcatalog-in-sqoop

单个方案都没有解决,但是综合两个地址中的方案解决了

—map-column-java和—map-column-hive两个参数都要显示给出;还需要设置—hive-drop-import-delims这样才能顺利导出数据。
bin/sqoop import --connect jdbc:oracle:thin:@172.21.62.200:1521:ORCL --username fetchuser --password fetch1q2w3e4R \ --table TB_NEWS --fields-terminated-by '\t' \ --hive-drop-import-delims \ --map-column-java CONTENT=String \ --hive-import --hive-overwrite --create-hive-table --hive-table news.TB_NEWS_TEST --delete-target-dir

##### 问题二:oracle数据库中Date类型倒入到hive中出现时分秒截断

参考地址:http://www.cnblogs.com/wrencai/p/3935877.html

用sqoop将oracle数据表倒入到hive中,oracle中Date型数据会出现时分秒截断问题,只保留了‘yyyy-MM-dd’,而不是’yyyy-MM-dd HH24:mi:ss’格式的,后面的‘HH24:mi:ss’被自动截断了,在对时间要求到秒级的分析处理中这种截断会产生问题。

在用sqoop倒入数据表是,添加—map-column-hive 和—map-column-java参数,来改变数据表列的默认映射类型(默认情况下sqoop倒入hive中Date类型会被映射成String),将Date列映射成Timestamp类型,在我的问题中我是通过sqoop创建job,进行数据表按时间增量倒入的,PASSTIME列的数据类型是Date,脚本如下:
sqoop job --create jobimport2hiveofv_vehicleinfo --import --hive-import --map-column-java PASSTIME=java.sql.Timestamp --map-column-hive PASSTIME=TIMESTAMP --incremental append --connect jdbc:oracle:thin:@118.228.196.29:1521/pmptgdbanalyze --username SAN --password PASS --verbose -m 1 --bindir /opt/sqoop-1.4.4/lib --table V_VEHICLEINFO --check-column PASSTIME --last-value '2014-04-20 12:00:00'
注意:
(1)java.sql.Timestamp要带包名写全,否则可能会出错。

(2)—map-column-java和—map-column-hive连个参数都要显示给出,如果只给出—map-column-hive那么只会改变hive中表列的数据类型,
而codegen生成的Tablename.java源文件中还会是java.sql.Date类型,这样在转换成hive表中的TIMESTAMP类型时,就会出错导致hive中的PASSTIME字段全部为null。
原因可能是由于Date类型默认格式‘yyyy-M-dd’,而转化到hive Timestamp类型时,严格要求按照’yyyy-mm-dd hh:mm:ss[.f…]’格式转换,参见hive官网timestamp格式说明。

(3)如果不设置—map-column-hive参数,只设置—map-column-java 为java.sq..Timestamp,也可以实现数据精确到时分秒,只不过以string类型保存到列hive中。
事实上,在我实验后,发现如果指定—mapcolumn-hive参数为timestamp,在java中使用对应的时间where比较条件时,无法查出数据,
反而,指定—map-column-hive参数为string,却能够在hive中和java代码中都能够使用时间列参与查询。

因此在设计Hive表的时候,一般都把字段设置成为String类型,这样方便处理。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值