sqoop 实现将postgresql表导入hive表

 更新时间:2020年12月31日 09:24:24   作者:空中的鱼1987  
这篇文章主要介绍了sqoop 实现将postgresql表导入hive表,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

使用sqoop导入数据至hive常用语句

直接导入hive表

sqoop import 
--connect jdbc:postgresql://ip/db_name
--username user_name 
--table table_name 
--hive-import -m 5 

内部执行实际分三部,1.将数据导入hdfs(可在hdfs上找到相应目录),2.创建hive表名相同的表,3,将hdfs上数据传入hive表中

sqoop根据postgresql表创建hive表

sqoop create-hive-table 
--connect jdbc:postgresql://ip/db_name 
--username user_name 
--table table_name 
--hive-table hive_table_name
( --hive-partition-key partition_name若需要分区则加入分区名称) 

导入hive已经创建好的表中

sqoop import 
--connect jdbc:postgresql://ip/db_name 
--username user_name 
--table table_name 
--hive-import -m 5 
--hive-table hive_table_name 
(--hive-partition-key partition_name --hive-partition-value partititon_value);

使用query导入hive表

sqoop import 
--connect jdbc:postgresql://ip/db_name 
--username user_name 
--query "select ,* from retail_tb_order where \$CONDITIONS" 
--hive-import -m 5 
--hive-table hive_table_name 
(--hive-partition-key partition_name --hive-partition-value partititon_value); 

注意:$CONDITIONS条件必须有,query子句若用双引号,则$CONDITIONS需要使用\转义,若使用单引号,则不需要转义。

遇到问题

若需要在导入hive数据表的前提下,再添加在原有关系型数据库中没有的一列数据如何解决。

首先,我们想到的是添加一个partition可很方便的添加“一列”数据,partition的使用很类似普通一列,常用的sql执行是没有问题的。

其次,想到在query的sql中添加一个常量或者一个变量,例如:”select 'hello',* from retail_tb_order where \$CONDITIONS“,执行后会报异常

12/08/28 14:41:31 INFO tool.CodeGenTool: Beginning code generation 
12/08/28 14:41:31 INFO manager.SqlManager: Executing SQL statement: select 'hello',* from retail_tb_order where (1 = 0) 
12/08/28 14:41:32 INFO manager.SqlManager: Executing SQL statement: select 'hello',* from retail_tb_order where (1 = 0) 
12/08/28 14:41:32 ERROR orm.ClassWriter: Cannot resolve SQL type 1111 
12/08/28 14:41:32 ERROR orm.ClassWriter: Cannot resolve SQL type 1111 
12/08/28 14:41:32 ERROR orm.ClassWriter: No Java type for SQL type 1111 for column _column_ 
12/08/28 14:41:32 ERROR orm.ClassWriter: No Java type for SQL type 1111 for column _column_ 
12/08/28 14:41:32 ERROR orm.ClassWriter: No Java type for SQL type 1111 for column _column_ 
12/08/28 14:41:32 ERROR orm.ClassWriter: No Java type for SQL type 1111 for column _column_ 
12/08/28 14:41:32 ERROR orm.ClassWriter: No Java type for SQL type 1111 for column _column_ 
12/08/28 14:41:32 ERROR orm.ClassWriter: No Java type for SQL type 1111 for column _column_ 
12/08/28 14:41:32 ERROR sqoop.Sqoop: Got exception running Sqoop: java.lang.NullPointerException 
java.lang.NullPointerException 
 at org.apache.sqoop.orm.ClassWriter.parseNullVal(ClassWriter.java:900) 
 at org.apache.sqoop.orm.ClassWriter.parseColumn(ClassWriter.java:925) 
 at org.apache.sqoop.orm.ClassWriter.generateParser(ClassWriter.java:999) 
 at org.apache.sqoop.orm.ClassWriter.generateClassForColumns(ClassWriter.java:1314) 
 at org.apache.sqoop.orm.ClassWriter.generate(ClassWriter.java:1138) 
 at org.apache.sqoop.tool.CodeGenTool.generateORM(CodeGenTool.java:82) 
 at org.apache.sqoop.tool.ImportTool.importTable(ImportTool.java:367) 
 at org.apache.sqoop.tool.ImportTool.run(ImportTool.java:453) 
 at org.apache.sqoop.Sqoop.run(Sqoop.java:145) 
 at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:65) 
 at org.apache.sqoop.Sqoop.runSqoop(Sqoop.java:181) 
 at org.apache.sqoop.Sqoop.runTool(Sqoop.java:220) 
 at org.apache.sqoop.Sqoop.runTool(Sqoop.java:229) 
 at org.apache.sqoop.Sqoop.main(Sqoop.java:238) 
 at com.cloudera.sqoop.Sqoop.main(Sqoop.java:57) 

该问题出现原因是sqoop ClassWriter类会在postgresql表中解析sql中的所有列,当解析常量'hello'时,数据库没有该列也就找不到相应的数据类型。

若要解决该问题应该需修改ClassWriter源码。

补充:使用Sqoop,最终导入到hive中的数据和原数据库中数据不一致解决办法

Sqoop是一款开源的工具,主要用于在Hadoop(Hive)与传统的数据库(mysql、postgresql...)间进行数据的传递,可以将一个关系型数据库(例如 : MySQL ,Oracle ,Postgres等)中的数据导进到Hadoop的HDFS中,也可以将HDFS的数据导进到关系型数据库中。

1.问题背景  

使用Sqoop把oracle数据库中的一张表,这里假定为student,当中的数据导入到hdfs中,然后再创建hive的external表,location到刚才保存到hdfs中数据的位置。最后发现对hive中表特定条件进行count时结果和oracle中结果不一致。

1.1 导入数据到hdfs中/user/hadoop/student路径下

sqoop import --connect "jdbc:oracle:thin:@//localhost:1521/student" --password "***" --username "***" --query "select * from student where name='zhangsan' and class_id='003' and \$CONDITIONS" --target-dir "/user/hadoop/student" --verbose -m 1

这个时候hdfs上/user/hadoop/student下就保存了从oracle上导入的表数据。

表数据在hdfs上是如何存储的呢?注意这一点,造成了最后产生结果不一致的错误。

我们来看一看在hdfs上数据是如何存储的。我们运行hadoop fs -cat /user/hadoop/student/part-m-00000,可以看到原来字段与字段之间都用‘,'分隔开,这是sqoop默认的,这时候,如果一个字段值当中包含‘,',再向hive中插入数据时分隔就会出错。因为hive也是用‘,'分隔的。

2.分析问题  

对hive中表select count(*) from student的结果和oracle中select count(*) from studeng的结果进行比较,发现条数是一样的,说明没有少load数据。那为什么对特定条件结果就会不一致,而且hive中条数比oracle中少。也就是同时运行select count(*) from student where class_id='003'

最后,发现hive用逗号分隔数据时,有几条数据字段内值包含有逗号,所以字段与值对应起来就乱套了,所以得不到正确结果。

我们建议用‘\001'来进行sqoop 导入数据时的 分割。也就是--fields-terminated-by <char>参数。

参考:http://sqoop.apache.org/docs/1.4.2/SqoopUserGuide.html#_large_objects

最后优化后的sqoop语句为:

sqoop import --connect "jdbc:oracle:thin:@//localhost:1521/student" --password "***" --username "***" --query "select * from student where name='zhangsan' and class_id='003' and \$CONDITIONS" --target-dir "/user/hadoop/student" --fields-terminated-by "\001" --verbose -m 1

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

相关文章

  • 聊聊PostgreSql table和磁盘文件的映射关系

    聊聊PostgreSql table和磁盘文件的映射关系

    这篇文章主要介绍了聊聊PostgreSql table和磁盘文件的映射关系,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • 基于PostgreSQL pg_hba.conf 配置参数的使用说明

    基于PostgreSQL pg_hba.conf 配置参数的使用说明

    这篇文章主要介绍了基于PostgreSQL pg_hba.conf 配置参数的使用说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • Postgresql中json和jsonb类型区别解析

    Postgresql中json和jsonb类型区别解析

    在我们的业务开发中,可能会因为特殊【历史,偷懒,防止表连接】经常会有JSON或者JSONArray类的数据存储到某列中,这个时候再PG数据库中有两种数据格式可以直接一对多或者一对一的映射对象,接下来通过本文介绍Postgresql中json和jsonb类型区别,需要的朋友可以参考下
    2024-06-06
  • 使用Postgresql 实现快速插入测试数据

    使用Postgresql 实现快速插入测试数据

    这篇文章主要介绍了使用Postgresql 实现快速插入测试数据,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • PostgreSQL时间日期的语法及注意事项

    PostgreSQL时间日期的语法及注意事项

    在开发过程中,经常要取日期的年,月,日,小时等值,PostgreSQL 提供一个非常便利的EXTRACT函数,这篇文章主要给大家介绍了关于PostgreSQL时间日期的语法及注意事项的相关资料,需要的朋友可以参考下
    2023-01-01
  • 解决PostgreSQL 执行超时的情况

    解决PostgreSQL 执行超时的情况

    这篇文章主要介绍了解决PostgreSQL 执行超时的情况,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • 关于PostgreSQL截取某个字段中的部分内容进行排序的问题

    关于PostgreSQL截取某个字段中的部分内容进行排序的问题

    这篇文章主要介绍了PostgreSQL截取某个字段中的部分内容进行排序,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06
  • postgresql 实现将字段为空的值替换为指定值

    postgresql 实现将字段为空的值替换为指定值

    这篇文章主要介绍了postgresql 实现将字段为空的值替换为指定值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • PostgreSQL 实现列转行问题

    PostgreSQL 实现列转行问题

    这篇文章主要介绍了PostgreSQL 实现列转行问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • Postgresql开启远程访问的步骤全纪录

    Postgresql开启远程访问的步骤全纪录

    postgre一般默认为本地连接,不支持远程访问,所以如果要开启远程访问,需要更改安装文件的配置。下面这篇文章主要给大家介绍了关于Postgresql开启远程访问的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。
    2018-03-03

最新评论