作者:huanghxn | 来源:互联网 | 2023-05-18 07:40
客户有需要需要把数据从传统数据库想hadoop平台迁移,他们利用sqoop将数据从oracle迁移到hive中。最近他们在迁移的时候碰到一个问题,说是从ORACLE以并行方式“抽取数
客户有需要需要把数据从传统数据库想hadoop平台迁移,他们利用sqoop将数据从oracle迁移到hive中。最近他们在迁移的时候碰到一个问题,说是从ORACLE以并行方式“抽取数据”抽取数据到HIVE用多个条件进行抽取没有调通。以下是他们发过来的脚本:
sqoop import --connect jdbc:mysql://hadoop-master:3306/hive --username root --table test --fields-terminated-by '\t' [--null-string '**‘] -m 1 --append --hive-import --hive-partition-key KEY --hive-partition-value VALUE
这里面有个问题是,目标表有多个分区,如果只是单个分区的话可以直接指定--hive-partition-key和--hive-partition-value这两个参数即可,可以这样做:
但是这样只能向单个分区中导入数据,于是我试着在sqoop语句中指定两个分区结果报错。在网上也没有找着类似的解决方案。我不知道是sqoop没有提供这样的功能还是我理解不全面,如果有能在一条句子里直接搞定希望回复我,让我长长见识。
由于sqoop在向hive中导入数据时,是先将数据上传到hdfs中,然后创建表,最后在将hdfs中的数据load到表目录下。受此启发,(我没有oracle数据库,用mysql代替)我们将所要解决的问题分为两步:
这是我的mysql中的测试数据:第一列为数据类型int,第二列为varchar2。
id name
1 zhangsan
2 wangwu
3 zhaoliu
4 wang
5 liujia
6 gao
7 lirui
8 lisi
假如我需要向test表中,partition(company=‘bonc’, group='bigdata')中导入数据,我们提前创建好表和分区:
首先创建表和分区:
CREATE TABLE test(id int, name string) PARTITIONED BY(company string, group string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
ALTER TABLE test ADD PARTITION(company='bonc', group='bigdata') LOCATION '/user/hive/warehouse/test/company=bonc/group=bigdata';
然后把数据仓库目录作为target直接将数据上传进去,实际上只是向hdfs中上传,并没有用到--hive-import
sqoop import --connect jdbc:mysql://hadoop-master:3306/hive --username root --password vmware --table test --target-dir '/user/hive/warehouse/test/bOnc=pezy/group=bigdata' --append --fields-terminated-by '\t' -m 1 --columns id,name --where 'id=4'
这样就将指定列和限定条件id=4的这条数据导入到了hive表中,注意一定加--append参数,否则是不能将数据导入到已经存在的目录中去。
最后用select * from test;结果显示正确。
首先,如果要向hive表的指定分区导入数据应该要用--hive-table, --hive-partition-key, --hive-partition-value这三个参数。但是这样只能向单个分区导入数据,无法指定多个分区;其次,--where条件中没有用and。由于咱的目标hive表有两个partition,而且无法直接在参数中多个partition(我在指定多个partition的时候报错),所以咱可以分两步解决这个问题:
1) 首先确保目标分区中没有数据,即/user/hive/warehouse/gm.db/gm_test/day_part=10/area_part=2105目录是空的;
2) 将数据直接上传到指定的数据仓库目录中。(--append 参数要指定,否则无法向已经存在的hdfs目录中导入数据)
/opt/mapr/sqoop/sqoop-1.2.0/bin/sqoop import --append --connect jdbc:oracle:thin:@132.194.36.55:1521:lndwres --username HADOOP --password HADOOP --target-dir "/user/hive/warehouse/gm.db/gm_test/day_part=10/area_part=2105" --m 10 --split-by part10 --table GM_TEST
--fields-terminated-by '\001'
--query "SELECT
DAY_ID, AREA_NO, ACCT_MONTH, ACCESS_NBR FROM GM_TEST WHERE
DAY_ID='10' AND
AREA_NO=2105
"
如果有更好的方法欢迎指出。