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

时间:2013-08-08 15:07:11

标签: database hadoop hive bigdata hiveql

我们希望将Hive查询的结果放到CSV文件中。我以为命令应该是这样的:

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

当我运行它时,它表示它已成功完成但我永远找不到该文件。如何找到此文件或者我应该以不同的方式提取数据?

谢谢!

18 个答案:

答案 0 :(得分:141)

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

根据the manual,您的查询会将数据存储在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

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

基于this patch-3682,我怀疑在使用Hive 0.11时可以使用更好的解决方案,但我无法自行测试。新语法应允许以下内容。

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

希望有所帮助。

答案 1 :(得分:21)

如果您想要一个CSV文件,那么您可以按照以下方式修改Lukas的解决方案(假设您使用的是Linux盒子):

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

答案 2 :(得分:4)

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

您也可能需要做一些诡计来将文件从'\ 001'转换为 - 分隔为CSV。您可以使用自定义CSV SerDe或对提取的文件进行后处理。

答案 3 :(得分:3)

如果您使用HUE,这也很简单。只需转到HUE中的Hive编辑器,执行您的配置单元查询,然后将结果文件保存为XLS或CSV,或者将结果文件保存到HDFS。

答案 4 :(得分: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

答案 5 :(得分: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。希望这能帮助那些寻求解决方案的人。

答案 6 :(得分: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步 - 将来自Hive仓库的blob复制到具有适当扩展名的新位置

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

答案 7 :(得分:2)

您可以使用INSERT ... DIRECTORY ...,如下例所示:

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

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

答案 8 :(得分:1)

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

当我想更改分隔符时,我使用SQL,如:

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

然后,将分隔符+“^A”视为新的分隔符。

答案 9 :(得分:0)

使用命令:

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

我有一个huge dataset,我试图组织其详细信息并确定攻击的类型以及每种攻击的数量。我在练习中使用的一个有效示例(还有更多细节)是这样的:

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

答案 10 :(得分:0)

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

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

答案 11 :(得分:0)

此shell命令将csv中的输出格式打印到output.txt,而没有列标题。

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

答案 12 :(得分:0)

我可能迟到了,但会帮助您解决问题:

回显“ COL_NAME1 | COL_NAME2 | COL_NAME3 | COL_NAME4”> SAMPLE_Data.csv 蜂巢-e' 选择不同的concat(COL_1,“ |”, COL_2,“ |”, COL_3,“ |”, COL_4) 来自table_Name where子句(如果需要); >> SAMPLE_Data.csv

答案 13 :(得分:0)

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

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

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

答案 14 :(得分:0)

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

就我而言,临时文件夹下的生成数据为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

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

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

答案 15 :(得分:0)

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

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

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

您还可以使用tr "|" ","来转换“ |”到“,”

答案 16 :(得分:0)

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

它将:

  1. 登录到堡垒主机。
  2. 普朗。
  3. 起义。
  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

答案 17 :(得分:0)

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