大数据学习21:sqoop 语法和常用命令和小案例

来源:互联网 发布:一键抠图软件电脑 编辑:程序博客网 时间:2024/06/06 00:52

1.1.0 sqoop 语法和常用命令
2.1.0 sqoop 典型用法
3.1.0 sqoop 的一个小案例
4.1.0 sqoop 的分区表导入导出

=======================================
1.1.0 sqoop 语法和常用命令
hive导入参数

  --hive-home   重写$HIVE_HOME    --hive-import          插入数据到hive当中,使用hive的默认分隔符    --hive-overwrite  重写插入    --create-hive-table  建表,如果表已经存在,该操作会报错!    --hive-table [table]  设置到hive当中的表名    --hive-drop-import-delims  导入到hive时删除 \n, \r, and \01     --hive-delims-replacement  导入到hive时用自定义的字符替换掉 \n, \r, and \01     --hive-partition-key          hive分区的key    --hive-partition-value   hive分区的值    --map-column-hive           类型匹配,sql类型对应到hive类型  

1.1.1 前期准备:
如果sqoop要连接mysql 或者 oracle 需要下载 相应的jdbc
放到 $SQOOP_HOME/lib/ 下 ,如果是CDH 那么放在

/opt/cloudera/parcels/CDH-5.4.10-1.cdh5.4.10.p0.16/lib/sqoop/lib 下mysql-connector-java-5.1.27-bin.jar ojdbc6.jar

如果要采用压缩,那么需要在hdfs编译的时候加上native ,否则无法采用压缩。
例子:mvn clean package -Pdist,native -DskipTests -Dtar

1.1.2 list 功能
列出SQL中的所有库

sqoop list-databases --connect jdbc:mysql://192.168.100.100:3306/ -username root -password 123456

连接SQL 并列出库中的表

sqoop list-tables --connect jdbc:mysql://192.168.100.100:3306/oozie --username root --password 123456sqoop list-tables --connect jdbc:mysql://192.168.100.100:3306/test --username root --password 123456sqoop list-tables --connect jdbc:oracle:thin:@192.168.4.11:1521:dg1  --username wxk --password wxk

1.1.3 导入 mysql –> hdfs [表如果没有主键,这样会报错,需要特殊指定]
直接导入:

sqoop import \--connect  jdbc:mysql://localhost:3306/sqoop \--username root \--password password \--table emp

默认splits = 4 ,通过 -m 1 来指定maptask数量,也就是指定结果集分片的数量。

导入放在哪里了呢?默认放在 /user/用户名 下

[root@hadoop002 lib]# hadoop fs -ls /user/rootFound 1 itemsdrwxr-xr-x   - root supergroup          0 2017-09-23 10:05 /user/root/emp

一些参数解释:
–query 和 –table –where 不能同时使用,必须要加 $CONDITIONS,如果 query 后面是”” 那么要写 \$CONDITIONS 转义字符。
最好把要抽取的列直接写入sql中,这样能避免报错。
-m 指定分片,也是指定maptask数量
–delete-target-dir 覆盖,自动先删再导
–mapreduce-job-name 指定mr作业的名字
–columns “A,B” 导出指定的列
–target-dir EMP_COLUMN 导出到指定的路径 这里 EMP_COLUMN 其实也是表名的意思
–where “sal > 2000” 条件语句,按条件导出

例子1:
将 emp 的部分列 sal > 2000 的数据 从mysql的sqoop的库中 导入到 hdfs 上,存放在 /user/root/EMP_COLUMN 路径,
指定mapreduce的作业名为emp-all ,如果已经存在,那么先删除再导入。

sqoop import \--connect  jdbc:mysql://localhost:3306/sqoop \--username root \--password password \--table emp \-m 1  \--delete-target-dir \--mapreduce-job-name emp-all \--columns "empno,ename,job,mgr,sal,deptno" \--target-dir EMP_COLUMN \--where "sal > 2000"

例子2:
通过 sql 将数据从 mysql 的sqoop库中导入到hdfs上,存放在/user/root/EMP_COLUMN 路径,
指定mapreduce的作业名为emp-all ,如果已经存在,那么先删除再导入,
将输出文件设置为 parquet 或者 sequencefile 格式。

sqoop import \--connect  jdbc:mysql://localhost:3306/sqoop \--username root \--password password \-m 1  \--delete-target-dir \--mapreduce-job-name emp-all \--columns "empno,ename,job,mgr,sal,deptno" \--target-dir EMP_COLUMN \--query 'select empno,ename,job,mgr,sal,deptno from emp where sal>2000 and $CONDITIONS'--as-parquetfile 或者 --as-sequencefile[root@hadoop002 ~]# hadoop fs -ls  /user/root/EMP_COLUMN/Found 3 itemsdrwxr-xr-x   - root supergroup          0 2017-09-24 04:24 /user/root/EMP_COLUMN/.metadatadrwxr-xr-x   - root supergroup          0 2017-09-24 04:24 /user/root/EMP_COLUMN/.signals-rw-r--r--   1 root supergroup       1714 2017-09-24 04:24 /user/root/EMP_COLUMN/d2ce0a72-51e2-4125-accc-deb449c2ac3a.parquet[root@hadoop002 ~]# hadoop fs -ls    /user/root/EMP_COLUMN/Found 2 items-rw-r--r--   1 root supergroup          0 2017-09-24 04:26 /user/root/EMP_COLUMN/_SUCCESS-rw-r--r--   1 root supergroup        587 2017-09-24 04:26 /user/root/EMP_COLUMN/part-m-00000

例子3:
将导入文件进行压缩 –compression-codec codec为hadoop的压缩模式,-z 为默认gzip

sqoop import \--connect  jdbc:mysql://localhost:3306/sqoop \--username root \--password password \-m 1  \--delete-target-dir \--mapreduce-job-name emp-all \--columns "empno,ename,job,mgr,sal,deptno" \--target-dir EMP_COLUMN \--query 'select empno,ename,job,mgr,sal,deptno from emp where sal>2000 and $CONDITIONS' \-z

如果用其他格式的压缩,需要配合hdfs上压缩格式使用。

--compression-codec snappy 163k不用压缩 210k

如何查看能用的压缩格式?

[root@hadoop002 native]# hadoop checknative -a17/09/26 04:04:31 INFO bzip2.Bzip2Factory: Successfully loaded & initialized native-bzip2 library system-native17/09/26 04:04:31 INFO zlib.ZlibFactory: Successfully loaded & initialized native-zlib libraryNative library checking:hadoop:  true /opt/software/hadoop-2.6.0-cdh5.7.0/lib/native/libhadoop.sozlib:    true /lib64/libz.so.1snappy:  true /opt/software/hadoop-2.6.0-cdh5.7.0/lib/native/libsnappy.so.1lz4:     true revision:99bzip2:   true /lib64/libbz2.so.1openssl: true /usr/lib64/libcrypto.so

例子4:
将多个表的统计结果导出到hdfs 这里好像不好指定具体哪些表,只能一次全导入了。需要进一步研究。

sqoop import-all-tables \--connect jdbc:mysql://localhost:3306/sqoop  \--username root \--password password \-m 1 \--delete-target-dir \--warehouse-dir /output/

多表导入,且每个表都要有主键

[root@hadoop002 ~]# hadoop fs -ls /outputFound 4 itemsdrwxr-xr-x   - root supergroup          0 2017-09-24 02:00 /output/deptdrwxr-xr-x   - root supergroup          0 2017-09-24 02:00 /output/empdrwxr-xr-x   - root supergroup          0 2017-09-24 02:01 /output/emp2drwxr-xr-x   - root supergroup          0 2017-09-24 02:01 /output/salgrade

例子5:
导出没有主键的表,并且使用多个mapper 要指定一下主键列,否则多 map 会报错。–split-by empno。
如果使用单个 map 是不会报错的

sqoop import \--connect  jdbc:mysql://localhost:3306/sqoop \--username root \--password password \-m 2  \--delete-target-dir \--mapreduce-job-name emp-all \--target-dir EMP3 \--table emp3 \--split-by empno  

如果不采用–split-by 并且采用多 maptask 会出现报错:

Error during import: No primary key could be found for table emp2. Please specify one with --split-by or perform a sequential import with '-m 1'.

例子6:oracle 的导入 ,oracle –> hdfs
将 t2 表从 oracle 中导入hdfs ,存放在/user/root/T2 路径,
指定mapreduce的作业名为T2-all ,如果已经存在,那么先删除再导入,
将输出文件设置为 parquet 或者 sequencefile 格式。

sqoop import \--connect jdbc:oracle:thin:@192.168.4.11:1521:dg1 \--username wxk --password wxk \--table T2 \-m 1 \--delete-target-dir \--mapreduce-job-name T2-all \--target-dir T2 \--compression-codec snappy 

例子7:分隔符
将mysql 的 emp2 导入到 hdfs ,放在 /user/root/EMP2_COLUMN 下,覆盖, 分隔符为 \t ,并采用direct

sqoop import \--connect jdbc:mysql://hadoop002:3306/sqoop \--username root \--password password \--table emp2 \-m 1 \--split-by empno \--delete-target-dir \--target-dir EMP2_COLUMN \--fields-terminated-by '\t'  \           [在注释中介绍为char,说明只能一个字符 $$$ = $]--null-non-string '0' --null-string '' \ [对于非string 的 null 设为0,对于string 的 null 设为空字符串]--direct                                 [可以加快传输速度 但是需要底层数据库支持【mysqlimport,比jdbc高效;oracle 支持】,可能会报错]

结果:

[root@hadoop002 ~]# hadoop fs -text /user/root/EMP2_COLUMN/part-m-000007369    SMITH   CLERK   7902    1980-12-17 00:00:00.0   800.00  0       20   [\t  分隔符]7369$SMITH$CLERK$7902$1980-12-17 00:00:00.0$800.00$0$20 [$$$ 分隔符]

会报这个错误,可能是由于mysql配置原因。

17/09/24 20:39:02 INFO mapreduce.Job: Task Id : attempt_1506081636263_0047_m_000000_0, Status : FAILEDError: java.io.IOException: Cannot run program "mysqldump": error=2, No such file or directory

例子8: 增量导入
增量导入,增量要设置3个参数

--delete-target-dir 和 append 不能一起用

将mysql 的 emp2 表中数据,以empno列为准,数值为7900以后的数值,以增量方式导入hdfs ,
设置分隔符为 \t ,null字符型为空,null非字符型为 0 。

sqoop import \--connect jdbc:mysql://hadoop002:3306/sqoop \--username root --password password \--table emp2 \-m 1 \--split-by empno --target-dir EMP2_COLUMN \--fields-terminated-by '\t' \--null-non-string '0' --null-string '' \--check-column empno \--incremental append \--last-value 7900 

结果:会产生新的文件,按照之前命令,last-value 值之后的为增量输入,产生新文件。
如果为新目录,则会生成一个part-m-00000,如果为老目录,会产生新的part-m-00001,不会删除之前的。

[root@hadoop002 ~]# hadoop fs -ls /user/root/EMP2_COLUMN/Found 3 items-rw-r--r--   1 root supergroup          0 2017-09-24 20:40 /user/root/EMP2_COLUMN/_SUCCESS-rw-r--r--   1 root supergroup        838 2017-09-24 20:40 /user/root/EMP2_COLUMN/part-m-00000-rw-r--r--   1 root supergroup        116 2017-09-24 20:49 /user/root/EMP2_COLUMN/part-m-00001[root@hadoop002 ~]# hadoop fs -text /user/root/EMP2_COLUMN/part-m-000017902    FORD    ANALYST 7566    1981-12-03 00:00:00.0   3000.00 0       207934    MILLER  CLERK   7782    1982-01-23 00:00:00.0   1300.00 0       10

例子9:sqoop eval 用法
用sqoop 去直接查询 mysql中的表,并显示

sqoop eval \--connect jdbc:mysql://hadoop002:3306/sqoop \--username root --password password \--query "select * from emp where deptno=10" 

例子10:sqoop 的脚本应用,–options-file 传递参数 工作中推荐使用。

[root@hadoop002 data]# cat emp.opt import --connect jdbc:mysql://hadoop002:3306/sqoop --username root --password password --table emp2-m 1 --split-by empno --delete-target-dir --target-dir EMP_OPTION --fields-terminated-by '\t' --null-non-string '0' --null-string '' 

注意:一行只能写一个参数,或者一个值!!!

sqoop --options-file /user/root/emp.opt 

运行结果成功

例子11:sqoop job 的使用
工作中建议封装为 sqoop job + crontab
sqoop job –help
注意,import 前面要加 空格

sqoop job --create myjob \-- import \--connect jdbc:mysql://hadoop002:3306/sqoop \--username root --password password \--table emp \--fields-terminated-by '\t' \-m 1 \--delete-target-dir 

查看 sqoop job

[root@hadoop002 data]# sqoop job --list 

删除 sqoop job

[root@hadoop002 conf]# sqoop job --delete myjob 

查看某个sqoop job

[root@hadoop002 data]# sqoop job --show myjob  要输入密码 password 

执行某个 sqoop job

[root@hadoop002 data]# sqoop job --exec myjob  要输入密码 password 

!!!!如何才能不输入密码,直接执行呢?

[root@hadoop002 conf]# vi sqoop-site.xml  添加  <property>    <name>sqoop.metastore.client.record.password</name>    <value>true</value>    <description>no use the password</description>  </property>

然后重启hive 创建 sqoop job 这样就可以了。
注意:如果是在改参数之前创建的job ,则没有用, 需要重建。

1.1.4 导出 hdfs -> mysql
首先要在mysql上创建表结构

mysql> create table emp_demo as select * from emp where 1=2;

然后用sqoop 导出到mysql
[注意大小写!!!!]
[每操作一次,数据会重复插入。如何解决?配合shell先删除,再插入]
[疑问:分隔符是怎么判断的?]

sqoop export \--connect jdbc:mysql://hadoop002:3306/sqoop \--username root --password password \--table emp_demo \-m 1 \--export-dir /user/root/EMP2/part-m-00000

1.1.5 导入 RDBMS -> hive
例子1:
将mysql 的 emp 表直接导入到 hive 中,并直接创建hive表。

sqoop import \--connect jdbc:mysql://hadoop002:3306/sqoop \--username root --password password \--table emp \-m 1 \--delete-target-dir \--hive-import \--create-hive-table \   #真实场景不要用 只能执行一次,而且生成的字段类型,用 desc 看可能不一样,一般要自己先创建hive的table --hive-table emp_import 

这里可能会报错:
17/09/25 03:16:04 WARN hive.TableDefWriter: Column empno had to be cast to a less precise type in Hive
如何解决呢?如下:

[root@hadoop002 lib]# cp hive-common-1.1.0-cdh5.7.0.jar /opt/software/sqoop-1.4.6-cdh5.7.0/lib/[root@hadoop002 lib]# cp hive-shims-* /opt/software/sqoop-1.4.6-cdh5.7.0/lib/

如何指定库? 而且desc 去看的话,字段类型会变。

例子2:
将mysql中的 emp 表导入 hive 中。会自动创建hive表!!!

sqoop import \--connect jdbc:mysql://hadoop002:3306/sqoop \--username root --password password \--table emp \-m 1 \--delete-target-dir \--hive-import \--hive-table emp_import     ##指定hive中具体的某个表

会发现插入了重复数据,如何解决这个问题?
一般是删除原表的数据,再次插入,truncate。
注意:truncate 不能删除外部表!因为外部表里的数据并不是存放在Hive Meta store中

例子3:分隔符问题!!!
注意:sqoop 从 mysql –> hive 只有在第一次创建的时候能指定分隔符,如果创建后,再使用fields-terminated-by 没法更改。

sqoop import \--connect jdbc:mysql://hadoop002:3306/sqoop \--username root --password password \--table emp \-m 1 \--delete-target-dir \--hive-import \--hive-table emp_import2 \--hive-overwrite \--fields-terminated-by "\t"

1.1.6 导出 hive –> RDBMS
例子1:
首先要在mysql上创建表结构

mysql> create table emp_demo as select * from emp where 1=2;

然后导出

sqoop export \--connect jdbc:mysql://hadoop002:3306/sqoop \--username root --password password \--table emp_demo \-m 1 \--export-dir /user/hive/warehouse/emp_import \--fields-terminated-by '\t'       

这里从hive导入到rdbms的时候,hive 表的分隔符是 \u0001 那么这里到 mysql的时候是用 \t 还是 \u001 ?

emp_import  表分隔符为 \u0001 导入到 mysql 时 分隔符用 \t 没有报错,而且mysql正常 emp_import2 表分隔符为 \t 导入到 mysql 时 分隔符用 \t 没有报错,而且mysql正常而且两种方式混合导入 mysql 表均正常

2.1.0 sqoop 典型用法

2.1.1 sqoop定时增量导入,导入前一天数据到hdfs
(1)增量数据导入

select strace,SDATETIME,NKIND,LNKID,STEMID from OTDRTEST1 where to_date(sdatetime,'yyyy-mm-dd,hh24:mi:ss') >= trunc(sysdate)-1 and to_date(sdatetime,'yyyy-mm-dd,hh24:mi:ss') < trunc(sysdate);
sudo sqoop import \--connect jdbc:oracle:thin:@192.168.100.200:1521:orcl \--username ALEX --password 123456 \--query "select strace,SDATETIME,NKIND,LNKID,STEMID from OTDRTEST1 where to_date(sdatetime,'yyyy-mm-dd,hh24:mi:ss') >= trunc(sysdate)-1 and to_date(sdatetime,'yyyy-mm-dd,hh24:mi:ss') < trunc(sysdate) and lnkid=1 and \$CONDITIONS" -m 1 \--target-dir  /user/hive/warehouse/ecmk/otdrtest11 --fields-terminated-by ","

(2)加载数据到hive表

sudo hive -e "load data inpath '/user/hive/warehouse/ecmk/otdrtest11/part-m-00000' into table otdrtest11"

(3)删除数据存放目录

sudo hadoop dfs -rmr /user/hive/warehouse/ecmk/otdrtest11

(4)清空回收站删除目录

sudo hadoop dfs -rmr /user/root/.Trash/Current/user/hive/warehouse/ecmk/otdrtest11

(5)定时任务

0 */2 * * *  /home/hadoop/sh/otdrtest2.sh10 22 * * *  /home/hadoop/sh/otdrtest1.sh*/5 * * * *  /home/hadoop/sh/lnkid.sh

2.2.1 集群hive数据迁移
(1)导出hive表数据到本地文件
导出hive表数据到本地文件(注意:加中间逗号分隔符)

hive (default)> insert overwrite local directory '/home/hadoop/exporthive' ROW FORMAT DELIMITED FIELDS TERMINATED BY',' select strace,sdatetime,nkind,lnkid,stemid from otdrtest1;

(2)本地文件压缩并远程发送
(3)创建hive表

hive (default)> CREATE TABLE OTDRTEST1100(STRACEFULL string,SDATETIME string,NKIND string,LNKID string,STEMID string ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

(4)加载本地文件到hive表

load data local inpath '/home/hadoop/exporthive/000000_0' into table otdrtest1100;

3.1.0 sqoop 的一个小案例
需求:mysql 中有 emp 表中有数据,不直接使用mysql统计,而是先将mysql的emp表数据通过sqoop抽取到hive中
然后使用hive,进行统计分析,统计的结果通过sqoop 导出到mysql 中
这是一个典型的ETL(extraction tranformation load)
分析:
1)在hive中创建emp对应的表
2)使用sqoop将mysql中的emp表导入到hive表中
3)在hive中统计分析(每个部门多少人),结果写入到hive结果表中
4)将hive结果表通过sqoop导出到mysql表中

要求:
1)所有步骤,手工执行,单任务执行。
2)shell 脚本
关键点:
我们在测试hdfs导入到关系型表的时候,数据是重复的
思路:在shell中直接访问mysql 表,先将数据清除。
1)truncate 可能适合这个作业
2)如果表是分区表,mysql 必然有一个字段对应分区字段,用shell去删分区的数据。
通过java jdbc 去读 ==> 表 ==> opt 文件,去执行即可

①手动
查看emp表

mysql> select * from emp;

创建hive 导入表

hive (default)> create table emp_m_to_h (empno      int ,                                        ename      string ,                                     job        string  ,                                    mgr        int    ,                                     hiredate   string  ,                                    sal        double  ,                                    comm       double  ,                                    deptno     int          )row format delimited fields terminated by '\t';

导入到hive 表

sqoop import \--connect jdbc:mysql://hadoop002:3306/sqoop \--username root --password password \--table emp \-m 1 \--hive-import \--hive-table emp_m_to_h \--hive-overwrite \--delete-target-dir \--fields-terminated-by '\t'

查看

[root@hadoop002 ~]# hadoop fs -ls  /user/hive/warehouse/emp_m_to_hFound 1 items-rwxr-xr-x   1 root supergroup        871 2017-09-25 06:59 /user/hive/warehouse/emp_m_to_h/part-m-00000
hive (default)> select deptno , count(1) from emp_m_to_h group by deptno ;

生成结果表

注意!!#hive (default)> create table result_h_to_m as select deptno , count(1) as sum_person from emp_m_to_h group by deptno ;

上面这样不行,因为生成的表格式不对,没有分隔符等,导出到mysql会报错。

create table result_h_to_m (deptno int,sum_person int) row format delimited fields terminated by '\t';insert overwrite table result_h_to_m select deptno , count(1) as sum_person from emp_m_to_h group by deptno ;

创建mysql上结果表

mysql> create table result_a (deptno int,sum_person int);

导出到mysql

sqoop export \--connect jdbc:mysql://hadoop002:3306/sqoop \--username root --password password \--table result_a \-m 1 \--export-dir /user/hive/warehouse/result_h_to_m \--fields-terminated-by '\t'     

②shell脚本

[root@hadoop002 ETL]# cat ETL.sh#!/bin/bash#mysql emp - > hive  emp_m_to_h - > calculate - > hive result_h_to_m  - > mysql result_a########改进版export MYSQL_BASE=/usr/local/mysqlexport PATH=$PATH:$MYSQL_BASE/binETL_LOG=/root/data/ETL/etl.logTODAY=`date`RUN_STR="export MYSQL_BASE=/usr/local/mysqlexport PATH=$PATH:$MYSQL_BASE/binETL_LOG=/root/data/ETL/etl.logTODAY=`date`mysql -uroot -ppassword sqoop -e \"select * from emp\"hive -e  \"create table if not exists emp_m_to_h (empno      int ,                                        ename      string ,                                     job        string  ,                                    mgr        int    ,                                     hiredate   string  ,                                    sal        double  ,                                    comm       double  ,                                    deptno     int) row format delimited fields terminated by '\t';\"  sqoop import \--connect jdbc:mysql://hadoop002:3306/sqoop \--username root --password password \--table emp \-m 1 \--hive-import \--hive-table emp_m_to_h \--hive-overwrite \--delete-target-dir \--fields-terminated-by '\t' hive -e \"create table if not exists result_h_to_m (deptno int,sum_person int) row format delimited fields terminated by '\t';\"hive -e \"insert overwrite table result_h_to_m select deptno , count(1) as sum_person from emp_m_to_h group by deptno ;\"mysql -uroot -ppassword sqoop -e \"drop table result_a;\"mysql -uroot -ppassword sqoop -e \"create table result_a (deptno int,sum_person int);\"sqoop export \--connect jdbc:mysql://hadoop002:3306/sqoop \--username root --password password \--table result_a \-m 1 \--export-dir /user/hive/warehouse/result_h_to_m \--fields-terminated-by '\t'   mysql -uroot -ppassword sqoop -e \"select * from result_a;\" > /root/data/ETL/result_a " echo $TODAY >> $ETL_LOG/bin/sh -c "$RUN_STR"  >> $ETL_LOGecho  `date +%Y/%m/%d-%H:%M:%H` === "success"  >> $ETL_LOG

4.1.0 sqoop 的分区表导入导出
PS:
创建分区表

hive> create table order_partition(order_number string,event_time string )partitioned by (event_month string)row format delimited fields terminated by '\t';#本地load data local inpath '/root/data/order_created.txt' overwrite into table order_partition partition(event_month = '201405')    或者 创建动态分区表hive> create table emp_dynamic_partition(empno int,ename string,job string,mgr int,hiredate string,sal double,comm double)partitioned by (deptno int) row format delimited fields terminated by '\t';hive> insert into table emp_dynamic_partition partition(deptno)select empno ,ename ,job ,mgr ,hiredate,sal ,comm ,deptno from emp;

4.1.1 导入 mysql(RDBMS) -> hive
–hive-partition-key hive分区的key
–hive-partition-value hive分区的值

例子1:对于只有单分区字段的导入
将emp表全部导入,成为某个分区表,分区表名为 emp_pardept10 ,分区为字段为 deptnumber ,值为 10

sqoop import \--connect jdbc:mysql://hadoop002:3306/sqoop \--username root --password password \--table emp \-m 1 \--delete-target-dir \--hive-import \--hive-table emp_pardept10 \--hive-overwrite \--fields-terminated-by "\t" \--hive-partition-key deptnumber \--hive-partition-value "10" [root@hadoop002 ETL]# hadoop fs -ls /user/hive/warehouse/emp_pardept10Found 1 itemsdrwxr-xr-x   - root supergroup          0 2017-09-26 08:38 /user/hive/warehouse/emp_pardept10/deptnumber=10

注意:分区字段必须不是表的字段,否则会报错!

例子2:将某个rdbms的表 用 分区表形式 导入 到 hive

sqoop import \--connect jdbc:mysql://hadoop002:3306/sqoop \--username root --password password \-m 1 \--delete-target-dir \--hive-import \--query 'select empno,ename,job,mgr,sal,deptno from emp where sal>2000 and $CONDITIONS' \--target-dir /user/hive/warehouse/emp_pardept10/ \--hive-table emp_pardept10 \--hive-overwrite \--fields-terminated-by "\t" \--hive-partition-key deptnumber \--hive-partition-value "10" 

注意:这里–query 和 –target-dir 必须连用

例子3:对于多分区字段的导入
不能再用–hive-table, –hive-partition-key, –hive-partition-value这三个参数。因为这样只能向单个分区导入数据,无法指定多个分区;其次,–where条件中没有用and。
所以可以分两步解决这个问题:
hive上创建track_log 为分区表 ;

mysql> create table track_log (id                         string ,url                        string ,cityId                     string )  PARTITIONED BY (ds string,hour string)  ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';

track_log18 为mysql(rdbms) 上的一个表;

1) 首先确保目标分区中没有数据,即/user/hive/warehouse/track_log/ds=20150827/hour=18目录是空的;
2) 将数据直接上传到指定的数据仓库目录中

sqoop import --connect  jdbc:mysql://localhost:3306/track_log \--username root --password Nokia123  \--table track_log18 \-m 1  \--target-dir /user/hive/warehouse/track_log/ds=20150827/hour=18 \--fields-terminated-by '\t'  //这个也很重要,否则查询一列时会返回多列
###上面这个命令可以看做mysql 导入到 hdfs 

结果:
开始没结果

hive> select id from track_log  limit 2;OKTime taken: 0.584 seconds

加入分区就好了

hive> alter table track_log add partition(ds='20150828' ,hour='18') location '/user/hive/warehouse/track_log/ds=20150828/hour=18';OKTime taken: 0.759 secondshive> select id from track_log limit 2;OK121508281810000000121508281810000001

4.1.2 导出 hive -> mysql(RDBMS)

sqoop export --connect jdbc:mysql://localhost:3306/test \--username root --password 123456 --table tablename \--export-dir /user/hive/warehouse/database/tablename1/part_date=2015-06-16 \--input-fields-terminated-by ','
非分区表:/user/hive/warehouse/database1/tablename分区表:/user/hive/warehouse/database1/tablename/part_date=2015-06-16

这是目前我对SQOOP的理解,如果有不准确的地方,欢迎指正哈!

原创粉丝点击