如何将HiveQL查询的结果输出到CSV?


79

我们希望将Hive查询的结果放入CSV文件。我认为该命令应如下所示:

insert overwrite directory '/home/output.csv' select books from table;

当我运行它时,它说成功完成了,但是我永远找不到该文件。如何找到该文件,或者应该以其他方式提取数据?

Answers:


145

尽管可以用来INSERT OVERWRITE从Hive中获取数据,但是对于您的特定情况,它可能不是最佳方法。首先让我解释一下INSERT OVERWRITE它的作用,然后再介绍从Hive表中获取tsv文件的方法。

根据手册,您的查询会将数据存储在HDFS的目录中。格式将不是csv。

写入文件系统的数据被序列化为文本,列之间用^ A隔开,行之间用换行符隔开。如果任何列都不是原始类型,那么这些列将序列化为JSON格式。

稍作修改(添加LOCAL关键字)会将数据存储在本地目录中。

INSERT OVERWRITE LOCAL DIRECTORY '/home/lvermeer/temp' select books from table;

当我运行类似的查询时,输出结果如下所示。

[lvermeer@hadoop temp]$ ll
total 4
-rwxr-xr-x 1 lvermeer users 811 Aug  9 09:21 000000_0
[lvermeer@hadoop temp]$ head 000000_0 
"row1""col1"1234"col3"1234FALSE
"row2""col1"5678"col3"5678TRUE

就个人而言,我通常会在命令行上直接通过Hive运行查询来进行此类操作,并将其通过管道传输到本地文件中,如下所示:

hive -e 'select books from table' > /home/lvermeer/temp.tsv

这给了我一个可以用制表符分隔的文件。希望对您也有帮助。

基于此3468补丁,我怀疑使用Hive 0.11时可以使用更好的解决方案,但我自己无法对此进行测试。新语法应允许以下内容。

INSERT OVERWRITE LOCAL DIRECTORY '/home/lvermeer/temp' 
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY ',' 
select books from table;

希望能有所帮助。


2
您是否知道插入覆盖本地和管道之间的性能差异,在这种情况下,近似的卷可能会成为问题,而且管道确保您将获得一个文件,而另一种方法为我们提供了一个目录,我们可能以后需要合并该目录
fd8s0 2014年

是否可以将HDFS中的数据导出为Sequence文件格式?
Nageswaran

1
我尝试了该解决方案(patch-3682),它对我来说效果很好-只是出于某种原因输出文件中不包含标头。注意,我已经设置了hive.cli.print.header = true; 在我的.hiverc中。为了值得,标题被打印到了终端上(这显然不是我想要的)。
彼得·科根

@ lukas-vermeer,使用“ INSERT OVERWRITE”方法创建表时,标头信息丢失。有没有办法获取标头信息?
ML_Passion '17

嗨,卢卡斯,您是如何使您的Shell在hadoop文件系统中工作的?
notilas

22

如果您想要CSV文件,则可以按以下方式修改Lukas的解决方案(假设您使用的是Linux系统):

hive -e 'select books from table' | sed 's/[[:space:]]\+/,/g' > /home/lvermeer/temp.csv

4
谢谢你 我正在使用一种变体,但是效果很好。请注意,这将输出逗号分隔的内容,不一定是某些人认为的CSV内容。CSV通常具有一些格式来处理带有逗号的数据(例如,使用双引号包装数据,对于带双引号的数据使用双双引号)。值得一提的是,添加“ --hiveconf hive.cli.print.header = True”参数也会在输出中获得标头。
2014年

这是最干净的解决方案
Dutta 2015年

1
这对我来说失败了,例如,日期时间字符串在日期和时间之间有空格。
威廉斯

@williaster sed's / \ t \ + /,/ g'这应该有助于解决此问题。
Sudhakar Chavan

如果tsv的文字包含逗号,则此功能将无效。(因为未引号的
无误

4

您应该使用CREATE TABLE AS SELECT(CTAS)语句在HDFS中创建一个目录,其中包含包含查询结果的文件。之后,您必须将这些文件从HDFS导出到常规磁盘,并将它们合并为一个文件。

您可能还需要做一些技巧才能将文件从'\ 001'转换为CSV。您可以使用自定义CSV SerDe或对提取的文件进行后处理。


如果要在后续的oozie管道步骤中使用输出,则此方法最好。
cerd

4

您可以使用INSERT…… DIRECTORY,如本例所示:

INSERT OVERWRITE LOCAL DIRECTORY '/tmp/ca_employees'
SELECT name, salary, address
FROM employees
WHERE se.state = 'CA';

OVERWRITELOCAL具有与以前相同的解释,并且路径将按照通常的规则进行解释。一个或多个文件将被写入/tmp/ca_employees,具体取决于调用的reducer数量。


3

如果您使用的是HUE,这也相当简单。只需转到HUE中的Hive编辑器,执行hive查询,然后将结果文件本地保存为XLS或CSV,或者您可以将结果文件保存到HDFS。


3

我一直在寻找类似的解决方案,但此处提到的解决方案不起作用。我的数据具有所有空白(空格,换行符,制表符)字符和逗号。

为了使列数据tsv安全,我用空格替换了列数据中的所有\ t字符,并在命令行上执行了python代码以生成一个csv文件,如下所示:

hive -e 'tab_replaced_hql_query' |  python -c 'exec("import sys;import csv;reader = csv.reader(sys.stdin, dialect=csv.excel_tab);writer = csv.writer(sys.stdout, dialect=csv.excel)\nfor row in reader: writer.writerow(row)")'

这创建了一个完全有效的csv。希望这对那些寻求此解决方案的人有所帮助。


1
现在是2016年,我们仍然必须跳过障碍才能做到这一点?我发现shravster的解决方案是迄今为止最好,最优雅的解决方案。
乔什(Josh)

您如何替换列数据中的所有\ t字符?您在查询中解决了该问题还是为其创建了单独的视图?
Naresh S

@NareshS,对不起您的回复。是的,这些列是在蜂巢中处理的,以便用空格替换制表符,或者如果必须,可以用<:tab>之类的替代符替换,或者类似的东西
sisanared

@sisanared,感谢您的回复。我看到我们需要对所有字符串列使用正则表达式替换,如果我们的表中有大量列> 100,这将很麻烦。是否有这种情况的快速解决方案
Naresh S

@NareshS,不幸的是,唯一的其他解决方案是在将数据放入分区之前清理数据。否则,您必须在对可能包含制表符的所有字符串列执行选择时执行此操作
sisanared

3

您可以使用配置单元字符串功能 CONCAT_WS( string delimiter, string str1, string str2...strn )

例如:

hive -e 'select CONCAT_WS(',',cola,colb,colc...,coln) from Mytable' > /home/user/Mycsv.csv

3

这是我发现输出HiveQL结果的最csv友好方式。
您不需要任何grep或sed命令来格式化数据,而是hive支持它,只需要添加outputformat的额外标签即可。

hive --outputformat=csv2 -e 'select * from <table_name> limit 20' > /path/toStore/data/results.csv

2

我遇到了类似的问题,这就是我能够解决的问题。

步骤1-如下所示将数据从Hive表加载到另一个表

DROP TABLE IF EXISTS TestHiveTableCSV;
CREATE TABLE TestHiveTableCSV 
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n' AS
SELECT Column List FROM TestHiveTable;

第2步-使用适当的扩展名将Blob从Hive仓库复制到新位置

Start-AzureStorageBlobCopy
-DestContext $destContext 
-SrcContainer "Source Container"
-SrcBlob "hive/warehouse/TestHiveTableCSV/000000_0"
-DestContainer "Destination Container"
-DestBlob "CSV/TestHiveTable.csv"

2
hive  --outputformat=csv2 -e "select * from yourtable" > my_file.csv

要么

hive  --outputformat=csv2 -e "select * from yourtable" > [your_path]/file_name.csv

对于ts​​v,只需在上述查询中将csv更改为tsv并运行查询


1

默认的分隔符是“ ^A”。在python语言中,它是“ \x01”。

当我想更改定界符时,我使用SQL,例如:

SELECT col1, delimiter, col2, delimiter, col3, ..., FROM table

然后,将定界符+“ ^A”作为新的定界符。


1

我尝试了各种选择,但这将是以下最简单的解决方案之一Python Pandas

hive -e 'select books from table' | grep "|" ' > temp.csv

df=pd.read_csv("temp.csv",sep='|')

您也可以使用tr "|" ","转换“ |” 至 ”,”


0

与上述Ray的答案类似,Hortonworks Data Platform中的Hive View 2.0还允许您运行Hive查询,然后将输出另存为csv。


0

如果您是从Windows执行此操作,则可以使用Python脚本hivehoney将表数据提取到本地CSV文件中。

它会:

  1. 登录到堡垒主机。
  2. 普朗
  3. kinit。
  4. 直线(与您的查询)。
  5. 将回声从直线上保存到Windows上的文件。

像这样执行:

set PROXY_HOST=your_bastion_host

set SERVICE_USER=you_func_user

set LINUX_USER=your_SOID

set LINUX_PWD=your_pwd

python hh.py --query_file=query.sql

0

只是为了在启动查询后介绍更多以下步骤: INSERT OVERWRITE LOCAL DIRECTORY '/home/lvermeer/temp' ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' select books from table;

以我为例,在temp文件夹下生成的数据是deflate格式化的,看起来像这样:

$ ls
000000_0.deflate  
000001_0.deflate  
000002_0.deflate  
000003_0.deflate  
000004_0.deflate  
000005_0.deflate  
000006_0.deflate  
000007_0.deflate

这是解压缩deflate文件并将所有内容放入一个csv文件的命令:

hadoop fs -text "file:///home/lvermeer/temp/*" > /home/lvermeer/result.csv

0

我可能迟到了这一步,但会帮助您回答:

echo“ COL_NAME1 | COL_NAME2 | COL_NAME3 | COL_NAME4”> SAMPLE_Data.csv配置单元-e'如果需要,请从table_Name where选择不同的concat(COL_1,“ |”,COL_2,“ |”,COL_3,“ |”,COL_4);' >> SAMPLE_Data.csv


0

此shell命令将csv中的输出格式打印为output.txt不包含列标题的格式。

$ hive --outputformat=csv2 -f 'hivedatascript.hql' --hiveconf hive.cli.print.header=false > output.txt

0

使用命令:

蜂巢-e“使用[数据库名称];从[表名称]限制10中选择*;” > /path/to/file/my_file_name.csv

我有一个庞大的数据集,其详细信息正试图组织和确定攻击的类型以及每种攻击的数量。我在实践中使用的一个有效示例(还有更多细节)如下所示:

hive -e "use DataAnalysis;
select attack_cat, 
case when attack_cat == 'Backdoor' then 'Backdoors' 
when length(attack_cat) == 0 then 'Normal' 
when attack_cat == 'Backdoors' then 'Backdoors' 
when attack_cat == 'Fuzzers' then 'Fuzzers' 
when attack_cat == 'Generic' then 'Generic' 
when attack_cat == 'Reconnaissance' then 'Reconnaissance' 
when attack_cat == 'Shellcode' then 'Shellcode' 
when attack_cat == 'Worms' then 'Worms' 
when attack_cat == 'Analysis' then 'Analysis' 
when attack_cat == 'DoS' then 'DoS' 
when attack_cat == 'Exploits' then 'Exploits' 
when trim(attack_cat) == 'Fuzzers' then 'Fuzzers' 
when trim(attack_cat) == 'Shellcode' then 'Shellcode' 
when trim(attack_cat) == 'Reconnaissance' then 'Reconnaissance' end,
count(*) from actualattacks group by attack_cat;">/root/data/output/results2.csv
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.