sqoop 實現(xiàn)將postgresql表導(dǎo)入hive表
使用sqoop導(dǎo)入數(shù)據(jù)至hive常用語句
直接導(dǎo)入hive表
sqoop import --connect jdbc:postgresql://ip/db_name --username user_name --table table_name --hive-import -m 5
內(nèi)部執(zhí)行實際分三部,1.將數(shù)據(jù)導(dǎo)入hdfs(可在hdfs上找到相應(yīng)目錄),2.創(chuàng)建hive表名相同的表,3,將hdfs上數(shù)據(jù)傳入hive表中
sqoop根據(jù)postgresql表創(chuàng)建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若需要分區(qū)則加入分區(qū)名稱)
導(dǎo)入hive已經(jīng)創(chuàng)建好的表中
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導(dǎo)入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需要使用\轉(zhuǎn)義,若使用單引號,則不需要轉(zhuǎn)義。
遇到問題
若需要在導(dǎo)入hive數(shù)據(jù)表的前提下,再添加在原有關(guān)系型數(shù)據(jù)庫中沒有的一列數(shù)據(jù)如何解決。
首先,我們想到的是添加一個partition可很方便的添加“一列”數(shù)據(jù),partition的使用很類似普通一列,常用的sql執(zhí)行是沒有問題的。
其次,想到在query的sql中添加一個常量或者一個變量,例如:”select 'hello',* from retail_tb_order where \$CONDITIONS“,執(zhí)行后會報異常
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)
該問題出現(xiàn)原因是sqoop ClassWriter類會在postgresql表中解析sql中的所有列,當(dāng)解析常量'hello'時,數(shù)據(jù)庫沒有該列也就找不到相應(yīng)的數(shù)據(jù)類型。
若要解決該問題應(yīng)該需修改ClassWriter源碼。
補充:使用Sqoop,最終導(dǎo)入到hive中的數(shù)據(jù)和原數(shù)據(jù)庫中數(shù)據(jù)不一致解決辦法
Sqoop是一款開源的工具,主要用于在Hadoop(Hive)與傳統(tǒng)的數(shù)據(jù)庫(mysql、postgresql...)間進行數(shù)據(jù)的傳遞,可以將一個關(guān)系型數(shù)據(jù)庫(例如 : MySQL ,Oracle ,Postgres等)中的數(shù)據(jù)導(dǎo)進到Hadoop的HDFS中,也可以將HDFS的數(shù)據(jù)導(dǎo)進到關(guān)系型數(shù)據(jù)庫中。
1.問題背景
使用Sqoop把oracle數(shù)據(jù)庫中的一張表,這里假定為student,當(dāng)中的數(shù)據(jù)導(dǎo)入到hdfs中,然后再創(chuàng)建hive的external表,location到剛才保存到hdfs中數(shù)據(jù)的位置。最后發(fā)現(xiàn)對hive中表特定條件進行count時結(jié)果和oracle中結(jié)果不一致。
1.1 導(dǎo)入數(shù)據(jù)到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上導(dǎo)入的表數(shù)據(jù)。
表數(shù)據(jù)在hdfs上是如何存儲的呢?注意這一點,造成了最后產(chǎn)生結(jié)果不一致的錯誤。
我們來看一看在hdfs上數(shù)據(jù)是如何存儲的。我們運行hadoop fs -cat /user/hadoop/student/part-m-00000,可以看到原來字段與字段之間都用‘,'分隔開,這是sqoop默認的,這時候,如果一個字段值當(dāng)中包含‘,',再向hive中插入數(shù)據(jù)時分隔就會出錯。因為hive也是用‘,'分隔的。
2.分析問題
對hive中表select count(*) from student的結(jié)果和oracle中select count(*) from studeng的結(jié)果進行比較,發(fā)現(xiàn)條數(shù)是一樣的,說明沒有少load數(shù)據(jù)。那為什么對特定條件結(jié)果就會不一致,而且hive中條數(shù)比oracle中少。也就是同時運行select count(*) from student where class_id='003'
最后,發(fā)現(xiàn)hive用逗號分隔數(shù)據(jù)時,有幾條數(shù)據(jù)字段內(nèi)值包含有逗號,所以字段與值對應(yīng)起來就亂套了,所以得不到正確結(jié)果。
我們建議用‘\001'來進行sqoop 導(dǎo)入數(shù)據(jù)時的 分割。也就是--fields-terminated-by <char>參數(shù)。
參考:http://sqoop.apache.org/docs/1.4.2/SqoopUserGuide.html#_large_objects
最后優(yōu)化后的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
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。如有錯誤或未考慮完全的地方,望不吝賜教。
相關(guān)文章
postgresql 中的COALESCE()函數(shù)使用小技巧
這篇文章主要介紹了postgresql 中的COALESCE()函數(shù)使用小技巧,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01對PostgreSQL中的慢查詢進行分析和優(yōu)化的操作指南
在數(shù)據(jù)庫的世界里,慢查詢就像是路上的絆腳石,讓數(shù)據(jù)處理的道路變得崎嶇不平,想象一下,你正在高速公路上飛馳,突然遇到一堆減速帶,那感覺肯定糟透了,本文介紹了怎樣對?PostgreSQL?中的慢查詢進行分析和優(yōu)化,需要的朋友可以參考下2024-07-07使用postgresql 模擬批量數(shù)據(jù)插入的案例
這篇文章主要介紹了使用postgresql 模擬批量數(shù)據(jù)插入的案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01PostgreSQL13基于流復(fù)制搭建后備服務(wù)器的方法
這篇文章主要介紹了PostgreSQL13基于流復(fù)制搭建后備服務(wù)器,后備服務(wù)器作為主服務(wù)器的數(shù)據(jù)備份,可以保障數(shù)據(jù)不丟,而且在主服務(wù)器發(fā)生故障后可以提升為主服務(wù)器繼續(xù)提供服務(wù)。需要的朋友可以參考下2022-01-01PostgreSQL中date_trunc函數(shù)的語法及一些示例
這篇文章主要給大家介紹了關(guān)于PostgreSQL中date_trunc函數(shù)的語法及一些示例的相關(guān)資料,DATE_TRUNC函數(shù)是PostgreSQL數(shù)據(jù)庫中用于截斷日期部分的函數(shù),文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-04-04