数据导出的方式可以根据导出的地方不一样分为三种:
(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