我使用此Hive查询将表导出为CSV文件。
INSERT OVERWRITE DIRECTORY '/user/data/output/test' select column1, column2 from table1;
生成的文件'000000_0'没有逗号分隔符
这是生成CSV文件的正确方法吗?如果不是,请告诉我如何生成CSV文件?
答案 0 :(得分:52)
或使用此
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
。
答案 1 :(得分:47)
如果您使用的是Hive 11或更高版本,则可以将INSERT
语句与LOCAL
关键字一起使用。
示例:
insert overwrite local directory '/home/carter/staging' row format delimited fields terminated by ',' select * from hugetable;
请注意,这可能会创建多个文件,您可能希望在导出完成后在客户端连接它们。
使用此方法意味着您无需担心源表的格式,可以基于任意SQL查询进行导出,并可以选择自己的分隔符和输出格式。
答案 2 :(得分:34)
这应该对你有用
标签分隔
hive -e 'select * from some_table' > /home/yourfile.tsv
以逗号分隔
hive -e 'select * from some_table' | sed 's/[\t]/,/g' > /home/yourfile.csv
答案 3 :(得分:21)
生成报告后,您无法为查询输出设置分隔符(正如您所做的那样)。
您可以将分隔符更改为逗号。
它带有默认分隔符\001
(不可分割的字符)。
hadoop fs -cat /user/data/output/test/* |tr "\01" "," >>outputwithcomma.csv
答案 4 :(得分:8)
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
答案 5 :(得分:6)
最新版本的hive附带此功能。
INSERT OVERWRITE LOCAL DIRECTORY '/home/lvermeer/temp'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
select * from table;
这样您就可以选择自己的分隔符和文件名。 只需注意“ OVERWRITE ”,它就会尝试删除上述文件夹中的所有内容。
答案 6 :(得分: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"
...等等
答案 7 :(得分: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
来限制数据的大小,因为我有一个庞大的表,但您可以将其删除以导出整个表。
答案 8 :(得分:2)
在这里使用Hive仓库目录,您可以导出数据而不是Hive表。 首先给出hive仓库路径,然后在你想要存储.csv文件的本地路径之后 这个命令如下: -
hadoop fs -cat /user/hdusr/warehouse/HiveDb/tableName/* > /users/hadoop/test/nilesh/sample.csv
答案 9 :(得分:1)
我有类似的问题,这就是我能够解决的问题。
步骤1 - 将数据从hive表加载到另一个表中,如下所示
DROP TABLE IF EXISTS TestHiveTableCSV; CREATE TABLE TestHiveTableCSV行格式删除字段由','终止线路终止于' \ n'如 SELECT列表FROM TestHiveTable;
步骤2 - 将hb仓库中的blob复制到具有适当扩展名的新位置
Start-AzureStorageBlobCopy
-DestContext $destContext
-SrcContainer" Source Container"-SrcBlob "hive/warehouse/TestHiveTableCSV/000000_0"
-DestContainer" Destination Container" ` -DestBlob" CSV / TestHiveTable.csv"
希望这有帮助!
最诚挚的问候, Dattatrey Sindol(达塔) http://dattatreysindol.com
答案 10 :(得分:1)
有一些方法可以更改默认分隔符,如其他答案所示。
还有一些方法可以使用一些bash脚本将原始输出转换为csv。但是要考虑3个分隔符,而不仅仅是\ 001。当你的hive表有maps时,事情会变得复杂一些。
我写了一个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脚本,可以处理数据库导出 在多个文件中分段并具有默认分隔符。它会 输出一个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
关于the gist
的更多解释答案 11 :(得分:1)
如果要从Windows进行操作,则可以使用Python脚本hivehoney将表数据提取到本地CSV文件中。
它将:
像这样执行它:
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
答案 12 :(得分: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文件,其中包含查询的结果行,但这些行之间也包含日志消息。为了解决此问题,我尝试了this,但没有结果。
因此,为解决所有这些问题,我创建了一个执行查询列表的脚本,创建了一个文件夹(带有时间戳),用于存储结果,重命名获得的文件,删除不必要的文件,并分别添加相应的内容标头。
#!/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
答案 13 :(得分:0)
下面是我用来将Hive表数据作为带有标题的单个命名CSV文件导出到HDFS的端到端解决方案。
(不幸的是,无法使用一个HQL语句)
它由几个命令组成,但我认为它非常直观,并且不依赖于Hive表的内部表示,该表示可能会不时发生变化。
如果要将数据导出到与HDFS相对的本地文件系统中,请用“本地目录”替换“目录”。
# 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
答案 14 :(得分:0)
尝试
hive --outputformat==csv2 -e "select * from YOUR_TABLE";
这对我有用
我的蜂巢版本是“ Hive 3.1.0.3.1.0.0-78”
答案 15 :(得分:0)
这是在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;