[英]How do I export a CSV file into Hive table with records value with comma?
[英]How to export a Hive table into a CSV file?
我使用此 Hive 查詢將表導出到 CSV 文件中。
INSERT OVERWRITE DIRECTORY '/user/data/output/test' select column1, column2 from table1;
生成的文件“000000_0”沒有逗號分隔符
這是生成 CSV 文件的正確方法嗎? 如果沒有,請告訴我如何生成 CSV 文件?
或使用這個
hive -e 'select * from your_Table' | sed 's/[\t]/,/g' > /home/yourfile.csv
您還可以在SELECT
之前指定屬性set hive.cli.print.header=true
以確保創建標題和數據並將其復制到文件。 例如:
hive -e 'set hive.cli.print.header=true; select * from your_Table' | sed 's/[\t]/,/g' > /home/yourfile.csv
如果您不想寫入本地文件系統,請使用hadoop fs -put
命令將sed
命令的輸出通過管道hadoop fs -put
回HDFS
。
使用Cyberduck 之類的東西 SFTP 到您的文件也可能很方便,或者您可以使用scp
通過終端/命令提示符進行連接。
如果您使用的是 Hive 11 或更高版本,則可以使用帶有LOCAL
關鍵字的INSERT
語句。
例子:
insert overwrite local directory '/home/carter/staging' row format delimited fields terminated by ',' select * from hugetable;
請注意,這可能會創建多個文件,您可能希望在完成導出后在客戶端連接它們。
使用這種方法意味着您無需擔心源表的格式,可以基於任意 SQL 查詢導出,並且可以選擇自己的分隔符和輸出格式。
那應該對你有用
制表符分隔
hive -e 'select * from some_table' > /home/yourfile.tsv
逗號分隔
hive -e 'select * from some_table' | sed 's/[\\t]/,/g' > /home/yourfile.csv
生成報告后,您不能為查詢輸出設置分隔符(就像您所做的那樣)。
您可以將分隔符更改為逗號。
它帶有默認分隔符\\001
(不可見字符)。
hadoop fs -cat /user/data/output/test/* |tr "\01" "," >>outputwithcomma.csv
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
最新版本的 hive 帶有此功能。
INSERT OVERWRITE LOCAL DIRECTORY '/home/lvermeer/temp'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
select * from table;
這樣您就可以選擇自己的分隔符和文件名。 請小心“ OVERWRITE ”,它會嘗試從提到的文件夾中刪除所有內容。
我使用簡單的 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 regex)
結果將類似於常規 csv:
"col1","col2","col3"
……等等
以下腳本應該適合您:
#!/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
來限制數據的大小,因為我有一個很大的表,但是你可以刪除它來導出整個表。
在這里使用 Hive 倉庫目錄,您可以導出數據而不是 Hive 表。 首先給出 hive 倉庫路徑,然后給出要存儲 .csv 文件的本地路徑對於此命令如下:-
hadoop fs -cat /user/hdusr/warehouse/HiveDb/tableName/* > /users/hadoop/test/nilesh/sample.csv
我有一個類似的問題,這就是我能夠解決它的方式。
步驟 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 "Source Container"-SrcBlob "hive/warehouse/TestHiveTableCSV/000000_0"
-DestContainer "Destination Container" ` -DestBlob "CSV/TestHiveTable.csv"
希望這可以幫助!
最好的問候, Dattatrey Sindol (Datta) http://dattatreysindol.com
如其他答案所示,有多種方法可以更改默認分隔符。
還有一些方法可以使用一些 bash 腳本將原始輸出轉換為 csv。 有 3 個分隔符需要考慮,而不僅僅是 \\001。 當您的 hive table 有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
關於要點的更多解釋
如果您是從 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
問題解決方案很好,但我在兩者中都發現了一些問題:
正如 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
嘗試
hive --outputformat==csv2 -e "select * from YOUR_TABLE";
這對我有用
我的配置單元版本是“Hive 3.1.0.3.1.0.0-78”
這是在 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;
下面是我用來將 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.