簡體   English   中英

如何將 Hive 表導出為 CSV 文件?

[英]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 -putHDFS

使用Cyber​​duck 之類的東西 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 文件。

它會:

  • 登錄堡壘主機。
  • 布倫。
  • 基尼特。
  • 直線(與您的查詢)。
  • 將回聲從直線保存到 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

問題解決方案很好,但我在兩者中都發現了一些問題:

  • 正如 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM