66

我使用此 Hive 查询将表导出到 CSV 文件中。

INSERT OVERWRITE DIRECTORY '/user/data/output/test' select column1, column2 from table1;

生成的文件“000000_0”没有逗号分隔符

这是生成 CSV 文件的正确方法吗?如果没有,请告诉我如何生成 CSV 文件?

4

17 回答 17

84

或使用这个

hive -e 'select * from your_Table' | sed 's/[\t]/,/g'  > /home/yourfile.csv

您还可以set hive.cli.print.header=true在 之前指定属性SELECT以确保创建标头和数据并将其复制到文件中。例如:

hive -e 'set hive.cli.print.header=true; select * from your_Table' | sed 's/[\t]/,/g'  > /home/yourfile.csv

如果您不想写入本地文件系统,请将sed命令的输出通过管道传输回HDFS使用该hadoop fs -put命令。

使用Cyber​​duck之类的 SFTP 到您的文件也可能很方便,或者您可以使用scp通过终端/命令提示符进行连接。

于 2014-05-29T23:46:41.543 回答
54

如果您使用的是 Hive 11 或更高版本,则可以使用带有关键字的INSERT语句。LOCAL

例子:

insert overwrite local directory '/home/carter/staging' row format delimited fields terminated by ',' select * from hugetable;

请注意,这可能会创建多个文件,您可能希望在完成导出后在客户端将它们连接起来。

使用这种方式意味着您无需担心源表的格式,可以根据任意 SQL 查询导出,并且可以选择自己的分隔符和输出格式。

于 2013-11-01T15:59:37.263 回答
43

那应该对你有用

  • 制表符分隔

    hive -e 'select * from some_table' > /home/yourfile.tsv
  • 逗号分隔

    hive -e 'select * from some_table' | sed 's/[\t]/,/g' > /home/yourfile.csv
于 2014-05-02T10:24:06.537 回答
23

在生成报告后(如您所做的那样),您不能有查询输出的分隔符​​。

您可以将分隔符更改为逗号。

它带有默认分隔符\001(不可见字符)。

hadoop fs -cat /user/data/output/test/* |tr "\01" "," >>outputwithcomma.csv

也检查一下

于 2013-06-13T12:44:49.790 回答
11
INSERT OVERWRITE LOCAL DIRECTORY '/home/lvermeer/temp' ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' select * from table; 

是正确答案。

如果记录数真的很大,根据生成的文件数

以下命令只会给出部分结果。

hive -e 'select * from some_table' > /home/yourfile.csv
于 2015-10-02T18:29:18.033 回答
8

最新版本的 hive 带有此功能。

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

这样您就可以选择自己的分隔符和文件名。请注意“覆盖”它会尝试从提到的文件夹中删除所有内容。

于 2015-03-23T09:16:46.700 回答
4

我使用简单的 linux shell 管道 + perl 将 hive 生成​​的输出从 tsv 转换为 csv。

hive -e "SELECT col1, col2, … FROM table_name" | perl -lpe 's/"/\\"/g; s/^|$/"/g; s/\t/","/g' > output_file.csv

(前段时间我从 stackoverflow 中的某个人那里得到了更新的 perl 正则表达式)

结果将类似于常规 csv:

"col1","col2","col3"... 等等

于 2015-03-22T04:45:16.313 回答
4

以下脚本应该适合您:

#!/bin/bash
hive -e "insert overwrite local directory '/LocalPath/'
row format delimited fields terminated by ','
select * from Mydatabase,Mytable limit 100"
cat /LocalPath/* > /LocalPath/table.csv

由于我有一个巨大的表,我曾经limit 100限制数据的大小,但是您可以删除它以导出整个表。

于 2018-03-21T12:07:57.473 回答
2

Here using Hive warehouse dir you can export data instead of Hive table. first give hive warehouse path and after local path where you want to store the .csv file For this command is bellow :-

hadoop fs -cat /user/hdusr/warehouse/HiveDb/tableName/* > /users/hadoop/test/nilesh/sample.csv
于 2017-11-03T03:40:03.713 回答
1

我有一个类似的问题,这就是我能够解决它的方法。

第 1 步 - 将 hive 表中的数据加载到另一个表中,如下所示

如果存在则删除表 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“源容器” -SrcBlob "hive/warehouse/TestHiveTableCSV/000000_0" -DestContainer“目标容器”`-DestBlob“CSV/TestHiveTable.csv”

希望这可以帮助!

最好的问候, Dattatrey Sindol (Datta) http://dattatreysindol.com

于 2014-05-29T14:19:10.970 回答
1

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

它会:

  • 登录堡垒主机。
  • 布伦。
  • 基尼特。
  • 直线(与您的查询)。
  • 将直线的回声保存到 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
于 2018-09-04T18:42:22.053 回答
1

问题解决方案很好,但我发现两者都有一些问题:

  • 正如 Carter Shanklin 所说,使用此命令,我们将获得一个 csv 文件,其中包含指定路径中的查询结果:

    insert overwrite local directory '/home/carter/staging' row format delimited fields terminated by ',' select * from hugetable;
    

    这个解决方案的问题是获得的 csv 没有标题,并且会创建一个不是 CSV 的文件(所以我们必须重命名它)。

  • 正如 user1922900 所说,使用以下命令,我们将获得一个 CSV 文件,其中包含指定文件中的查询结果和标题:

    hive -e 'select * from some_table' | sed 's/[\t]/,/g' > /home/yourfile.csv
    

    使用此解决方案,我们将获得一个包含查询结果行的 CSV 文件,但这些行之间也包含日志消息。作为这个问题的解决方案,我尝试了这个,但没有结果。

因此,为了解决所有这些问题,我创建了一个执行查询列表的脚本,创建一个文件夹(带有时间戳),用于存储结果,重命名获得的文件,删除不需要的文件,并添加相应的标题。

 #!/bin/sh
 QUERIES=("select * from table1" "select * from table2")
 IFS=""
 directoryname=$(echo "ScriptResults$timestamp")
 mkdir $directoryname 
 counter=1 
for query in ${QUERIES[*]}
 do 
     tablename="query"$counter 
     hive -S -e "INSERT OVERWRITE LOCAL DIRECTORY '/data/2/DOMAIN_USERS/SANUK/users/$USER/$tablename' ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' $query ;"
     hive -S -e "set hive.cli.print.header=true; $query limit 1" | head -1 | sed 's/[\t]/,/g' >> /data/2/DOMAIN_USERS/SANUK/users/$USER/$tablename/header.csv
     mv $tablename/000000_0 $tablename/$tablename.csv
     cat $tablename/$tablename.csv >> $tablename/header.csv.
     rm $tablename/$tablename.csv
     mv $tablename/header.csv $tablename/$tablename.csv 
     mv $tablename/$tablename.csv $directoryname
     counter=$((counter+1))
     rm -rf $tablename/ 
 done
于 2018-11-21T09:31:05.320 回答
1

这是在 Hive 的 SQL 中执行此操作的一种更简单的方法:

set hive.execution.engine=tez;
set hive.merge.tezfiles=true;
set hive.exec.compress.output=false;

INSERT OVERWRITE DIRECTORY '/tmp/job/'
ROW FORMAT DELIMITED
FIELDS TERMINATED by ','
NULL DEFINED AS ''
STORED AS TEXTFILE
SELECT * from table;
于 2019-12-04T18:34:39.677 回答
1

如其他答案所示,有多种方法可以更改默认分隔符。

还有一些方法可以使用一些 bash 脚本将原始输出转换为 csv。不过,有 3 个分隔符需要考虑,而不仅仅是 \001。当您的蜂巢表有地图时,事情会变得更加复杂。

我编写了一个 bash 脚本,它可以处理来自 hive 的所有 3 个默认分隔符(\001 \002 和 \003)并输出 csv。脚本和更多信息在这里:

Hive 默认分隔符到 CSV

Hive 的默认分隔符是

Row Delimiter => Control-A ('\001')
Collection Item Delimiter => Control-B ('\002')
Map Key Delimiter => Control-C ('\003')

导出表格时有一些方法可以更改这些分隔符,但有时您可能仍然需要将其转换为 csv。

这是一个快速 bash 脚本,它可以处理在多个文件中分段并具有默认分隔符的 DB 导出。它将输出单个 CSV 文件。

假设段都具有命名约定 000*_0

INDIRECTORY="path/to/input/directory"
for f in $INDIRECTORY/000*_0; do 
  echo "Processing $f file.."; 
  cat -v $f | 
      LC_ALL=C sed -e "s/^/\"/g" | 
      LC_ALL=C sed -e "s/\^A/\",\"/g" | 
      LC_ALL=C sed -e "s/\^C\^B/\"\":\"\"\"\",\"\"/g" | 
      LC_ALL=C sed -e "s/\^B/\"\",\"\"/g" |  
      LC_ALL=C sed -e "s/\^C/\"\":\"\"/g" | 
      LC_ALL=C sed -e "s/$/\"/g" > $f-temp
done
echo "you,can,echo,your,header,here,if,you,like" > $INDIRECTORY/final_output.csv
cat $INDIRECTORY/*-temp >> $INDIRECTORY/final_output.csv
rm $INDIRECTORY/*-temp

关于要点的更多解释

于 2016-03-18T13:11:52.683 回答
1

尝试

hive --outputformat==csv2 -e "select * from YOUR_TABLE";

这对我有用

我的蜂巢版本是“蜂巢 3.1.0.3.1.0.0-78”

于 2019-11-29T05:58:37.127 回答
0

以上选项都不适合我。我想解决的几个问题

  • 如果值中有选项卡,则不应破坏 CSV 输出
  • 我需要自动添加头部而无需任何手动工作
  • 结构、数组或映射字段应为 JSON 编码

所以我创建了 UDF 来做到这一点。(有点惊讶 Hive 没有这个构建支持)

用法:

ADD JAR ivy://org.jsonex:HiveUDF:0.1.24?transitive=true;
CREATE TEMPORARY FUNCTION to_csv AS 'org.jsonex.hiveudf.ToCSVUDF';
SELECT to_csv(*) FROM someTable;  -- Default separator and headers
SELECT to_csv('{noHead:true}', *) FROM someTable;  -- No headers
SELECT to_csv('{headers:[,,,col3,]}', *) FROM someTable; -- Custom Headers
SELECT to_csv('{fieldSep:|,quoteChar:\"\\'\"}', *) FROM someTable" -- Custom fieldSep and quoteChar
于 2022-02-14T00:18:47.437 回答
0

下面是我用来将 Hive 表数据作为带有标题的单个命名 CSV 文件导出到 HDFS 的端到端解决方案。
(不幸的是,不可能用一个 HQL 语句来做)
它由几个命令组成,但我认为它非常直观,并且它不依赖于 Hive 表的内部表示,它可能会不时改变。
如果要将数据导出到本地文件系统而不是 HDFS,请将“DIRECTORY”替换为“LOCAL DIRECTORY”。

# cleanup the existing target HDFS directory, if it exists
sudo -u hdfs hdfs dfs -rm -f -r /tmp/data/my_exported_table_name/*

# export the data using Beeline CLI (it will create a data file with a surrogate name in the target HDFS directory)
beeline -u jdbc:hive2://my_hostname:10000 -n hive -e "INSERT OVERWRITE DIRECTORY '/tmp/data/my_exported_table_name' ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' SELECT * FROM my_exported_table_name"

# set the owner of the target HDFS directory to whatever UID you'll be using to run the subsequent commands (root in this case)
sudo -u hdfs hdfs dfs -chown -R root:hdfs /tmp/data/my_exported_table_name

# write the CSV header record to a separate file (make sure that its name is higher in the sort order than for the data file in the target HDFS directory)
# also, obviously, make sure that the number and the order of fields is the same as in the data file
echo 'field_name_1,field_name_2,field_name_3,field_name_4,field_name_5' | hadoop fs -put - /tmp/data/my_exported_table_name/.header.csv

# concatenate all (2) files in the target HDFS directory into the final CSV data file with a header
# (this is where the sort order of the file names is important)
hadoop fs -cat /tmp/data/my_exported_table_name/* | hadoop fs -put - /tmp/data/my_exported_table_name/my_exported_table_name.csv

# give the permissions for the exported data to other users as necessary
sudo -u hdfs hdfs dfs -chmod -R 777 /tmp/data/hive_extr/drivers
于 2019-05-27T17:59:58.503 回答