先看下面這條語句,它實現的功能是將特定日期的數據從mysql表中直接導入hive
$ sqoop import \
--connect jdbc:mysql://192.168.xx.xx:3306/db_name?useSSL=false \
--username xxx --password xxxxxx \
--query "select d.id, d.callsign, d.sobt from t_flight_baseinfo d where d.id is not null and d.sobt >= '2020-12-27' and \$CONDITIONS" \
--target-dir /user/hive/warehouse/datapros.db/t_flight_baseinfo/dt=2020-12-27 \
--delete-target-dir --fields-terminated-by '\t' --split-by d.id \
--hive-import --hive-overwrite --m 2 --direct \
--hive-database datapros --hive-table t_flight_baseinfo \
--hive-partition-key dt --hive-partition-value 2020-12-27
以下對命令中的參數作簡單說明:
--connect /--username / --password
很明顯,這是mysql數據庫的連接字符串
--query
這是選取數據的查詢語句。這里需要注意的是:
每條查詢語句必須要添加where條件;
末尾還要加上'$CONDITIONS'這個占位符;
當使用雙引號包裹住這個查詢語句時,'$CONDITIONS'前要加上轉義符變為'\$CONDITIONS',而如果使用單引號來包裹,就不用加轉義符!
--target-dir
mysql數據導入HDFS后的目標路徑(也即hive表的“數據文件”地址)
--delete-target-dir
導入前是否先刪除target-dir中定義的目錄(如果存在的話)
說明:這個參數比較重要!一般情況下,同一條導入語句,第一次執行時,要不要這個參數沒有關系,但如果是多次執行同一條導入語句,而又沒有提前手工刪除目標目錄時,就出出現“Output directory hdfs://hadoop:9820/somepath/${target_dir} already exists”,因此,這個參數一定要加上
--direct
使用直接導入模式,可以提高導入速度
--m 2
指定并行執行導入數據任務的map進程個數
--hive-database / --hive-table t_flight_baseinfo
指定導入到hive中的目標數據庫與數據表名稱
--hive-partition-key / --hive-partition-value
指定hive數據表的分區信息
--hive-overwrite
指定hive中的目標表可以被多次覆蓋寫入
--hive-import / --create-hive-table
1、create-hive-table:在hive中創建目標表(不管它是不是已經存在),如果目標表已經存在,就會給出“AlreadyExistsException(message:Table XXX already exists”出錯信息;
2、hive-import : hive-import在執行時,會自動生成一個建表的sql語句,當hive中不存在表時,它即自動創建目標表與存儲目錄,然后再導入數據;
mysql往hive帶分區表中導入實踐
1、在實踐中發現,當需要創建帶分區的表時,如果使用--create-hive-table參數,則每次都會提示表已存在錯誤(這個表確實是存在);不過,這個錯誤提示不影響命令的正確執行;
2、但是,如果不帶上這個參數,如果之前這個分區已存在 ,則會出現在hive表中能查到這個分區,但是它實際的存儲目錄已經被刪除(delete-target-dir參數的效果), hive-import會認為此分區已存在,就停止從mysql中往hdfs中導入數據,最后提示導入的數據numFiles=0,相當于分區表被清空;
3、如果不想每次都看到表已存在的錯誤提示,可以在執行導入命令之前,先執行一下 hive -e "alter table db_name.tb_name drop partition(partition_key='partition_value');"),先刪除這個分區,這樣hive-import就會創建hive表分區與重建存儲目錄。當然,這時候就不用加--create-hive-table參數了。