数据导出的方式可以根据导出的地方不一样分为三种:
(1):导出到本地文件系统;
(2):导出到HDFS中;
(3):导出到Hive的另一个表中。
为了避免单纯的文字,我们将一步一步的用命令进行说明:
一、导出到本地文件系统
hive (hive)> insert overwrite local directory '/usr/local/src'
> select * from wyp;
这条HQL的执行需要启用MapReduce完成,运行完这条语句之后,将会在本地文件系统的/usr/local/src/目录下生成文件,这个文件是Reduce产生的结果(这里生成的文件名是00000_0),我们可以看看这个文件的内容:
[root@liaozhongmin src]# more 000000_0
1lavimer2313878789088
2liaozhongmin2413787896578
3liaozemin2513409876785
注:其实实际情况下列与列之间是有分隔符的为^A(ASCALL码值是\00001)。另外一个千万千万要注意:语句中有一个overwrite关键字,意思是说会将导出来的内容覆盖掉你定义的目录下的所有内容,所以说你后面接的目录中一定不要有什么重要文件,否则就悲剧了!!!
另外一个要注意的是:和导入数据到Hive不一样,不能使用insert into来将数据导出:
hive (hive)> insert into local directory '/usr/local/src'
> select * from wyp;
15/01/26 16:50:11 INFO ql.Driver: <PERFLOG method=Driver.run>
15/01/26 16:50:11 INFO ql.Driver: <PERFLOG method=compile>
15/01/26 16:50:11 DEBUG parse.VariableSubstitution: Substitution is on: insert into local directory '/usr/local/src'
select * from wyp
15/01/26 16:50:11 INFO parse.ParseDriver: Parsing command: insert into local directory '/usr/local/src'
select * from wyp
FAILED: Parse Error: line 1:12 mismatched input 'local' expecting TABLE near 'into' in insert clause
15/01/26 16:50:11 ERROR ql.Driver: FAILED: Parse Error: line 1:12 mismatched input 'local' expecting TABLE near 'into' in insert clause
org.apache.hadoop.hive.ql.parse.ParseException: line 1:12 mismatched input 'local' expecting TABLE near 'into' in insert clause
at org.apache.hadoop.hive.ql.parse.ParseDriver.parse(ParseDriver.java:440)
at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:416)
at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:336)
at org.apache.hadoop.hive.ql.Driver.run(Driver.java:909)
at org.apache.hadoop.hive.cli.CliDriver.processLocalCmd(CliDriver.java:258)
at org.apache.hadoop.hive.cli.CliDriver.processCmd(CliDriver.java:215)
at org.apache.hadoop.hive.cli.CliDriver.processLine(CliDriver.java:406)
at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:689)
at org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:557)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.hadoop.util.RunJar.main(RunJar.java:156)
15/01/26 16:50:11 INFO ql.Driver: </PERFLOG method=compile start=1422262211433 end=1422262211443 duration=10>
15/01/26 16:50:11 INFO ql.Driver: <PERFLOG method=releaseLocks>
15/01/26 16:50:11 INFO ql.Driver: </PERFLOG method=releaseLocks start=1422262211443 end=1422262211443 duration=0>
hive (hive)>
二、导出到HDFS中
和导入数据到本地文件系统一样的简单,可以用下面的语句实现:
hive (hive)> insert overwrite directory '/hive_load_data'
> select * from wyp;
[root@liaozhongmin src]# hadoop fs -ls /hive_load_data;
Warning: $HADOOP_HOME is deprecated.
Found 1 items
-rw-r--r-- 1 root supergroup 82 2015-01-26 16:52 /hive_load_data/000000_0
[root@liaozhongmin src]# hadoop fs -text /hive_load_data/*
Warning: $HADOOP_HOME is deprecated.
1lavimer2313878789088
2liaozhongmin2413787896578
3liaozemin2513409876785
[root@liaozhongmin src]#
将会在HDFS的/hive_load_data目录下生成一个文件。
注意,和导出到本地文件系统的HQL相比少了一个local,不要混淆了。
三、导出到Hive的另一个表中
这其实就是Hive的数据导入方式,如下操作:
hive (hive)> insert into table test
> partition (age='25')
> select id,name,tel
> from wyp;
hive (hive)> select * from test;
OK
id name tel age
1 lavimer 13878789088 23
2 liaozhongmin 13787896578 24
1 lavimer 13878789088 25
2 liaozhongmin 13787896578 25
3 liaozemin 13409876785 25
3 liaozemin 13409876785 25
1 lavimer 13878789088 25
2 liaozhongmin 13787896578 25
3 liaozemin 13409876785 25
Time taken: 0.308 seconds
细心的读者可能会问,怎么导出数据到文件中,数据的列之间不是wyp表中设定的列分隔符呢?其实在Hive0.11.0版本之前,数据的导出是不能指定列之间的分隔符的,只能用默认的列分隔符,也就是上面的^A来分割,这样导出来的数据很不直观,看起来很不方便!
如果你用的版本是0.11.0,那么你可以再导出数据的时候指定列之间的分隔符,操作如下:
hive> insert overwrite local directory '/home/yangping.wu/local'
> row format delimited
> fields terminated by '\t'
> select * from wyp;
[wyp@master ~/local]$ vim 000000_0
5 wyp1 23 131212121212
6 wyp2 24 134535353535
7 wyp3 25 132453535353
8 wyp4 26 154243434355
1 wyp 25 13188888888888
2 test 30 13888888888888
3 zs 34 899314121
其实我们还可以用Hive的-e和-f参数来导出数据。其中-e后面接的是带双引号的sql语句;而-f后面接的是一个文件,文件的内容为一个sql语句,如下:
[root@liaozhongmin src]# hive -e "select * from hive.wyp" >> /usr/local/src/wyp.txt
这种方式得到的结果也是有分隔符的,如下:
[root@liaozhongmin src]# more /usr/local/src/wyp.txt
id name age tel
1 lavimer 23 13878789088
2 liaozhongmin 24 13787896578
3 liaozemin 25 13409876785
我们也可以使用-f的形式来达到相同的目的( -f后面接的是一个写有sql语句的文件)
[root@liaozhongmin src]# vim select_hql
[root@liaozhongmin src]# more select_hql
select * from hive.wyp;
[root@liaozhongmin src]# hive -f /usr/local/src/select_hql >> wyp2.txt
结果如下:
[root@liaozhongmin src]# more /usr/local/src/wyp2.txt
id name age tel
1 lavimer 23 13878789088
2 liaozhongmin 24 13787896578
3 liaozemin 25 13409876785
[root@liaozhongmin src]#
文章来自: 过往记忆: http://www.iteblog.com/archives/955