web-dev-qa-db-ja.com

HiveテーブルをCSVファイルにエクスポートする方法は?

このHiveクエリを使用して、テーブルをCSVファイルにエクスポートしました。

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

生成されたファイル「000000_0」にはカンマ区切り文字がありません

これはCSVファイルを生成する正しい方法ですか?いいえの場合、CSVファイルを生成する方法を教えてください。

52

またはこれを使用する

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コマンドの出力をHDFSにパイプで戻します。

58
user1922900

Hive 11以降を使用している場合は、INSERTステートメントをLOCALキーワードと共に使用できます。

例:

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

これにより複数のファイルが作成される場合があり、エクスポートが完了した後、クライアント側でそれらを連結する場合があることに注意してください。

このアプローチを使用すると、ソーステーブルの形式を気にする必要がなく、任意のSQLクエリに基づいてエクスポートでき、独自の区切り文字と出力形式を選択できます。

48
Carter Shanklin

それはあなたのために働くはずです

  • タブ区切り

    Hive -e 'select * from some_table' > /home/yourfile.tsv
  • カンマ区切り

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

レポートを生成した後(行ったように)、クエリ出力の区切り文字を使用することはできません。

区切り文字をカンマに変更できます。

デフォルトの区切り文字\001(不可視文字)が付属しています。

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

これもチェックしてください

22
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
8
Jsim

Hiveの最新バージョンにはこの機能が付属しています。

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

このようにして、独自の区切り文字とファイル名を選択できます。 「OVERWRITE」に注意してください。指定されたフォルダーからすべてを削除しようとします。

6
sunil

次のスクリプトが動作するはずです。

#!/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を使用してデータのサイズを制限しましたが、削除してテーブル全体をエクスポートできます。

4
HISI

単純なLinuxシェルパイピング+ 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"...など

4
Firman Gautama

ここでは、Hiveウェアハウスディレクトリを使用して、Hiveテーブルの代わりにデータをエクスポートできます。最初にHiveウェアハウスパスを指定し、.csvファイルを保存するローカルパスの後にこのコマンドを以下に示します。

hadoop fs -cat /user/hdusr/warehouse/HiveDb/tableName/* > /users/hadoop/test/nilesh/sample.csv
2
Nilesh Shinde

他の回答に示されているように、デフォルトの区切り文字を変更する方法があります。

また、bashスクリプトを使用して生の出力をcsvに変換する方法もあります。ただし、考慮すべき区切り文字は3つあり、\ 001だけではありません。 Hiveテーブルに maps があると、事態は少し複雑になります。

Hiveの3つのデフォルト区切り文字(\ 001\002および\ 003)をすべて処理し、csvを出力できるbashスクリプトを作成しました。スクリプトとその他の情報は次のとおりです。

Hiveデフォルト区切り文字をCSV

Hiveのデフォルトの区切り文字は

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

テーブルをエクスポートするときにこれらの区切り文字を変更する方法がありますが、それでもcsvに変換する必要がある場合があります。

複数のファイルにセグメント化され、デフォルトの区切り文字を持つDBエクスポートを処理できるクイック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 の詳細説明

1
alex9311

私は同様の問題を抱えていましたが、これは私がそれを解決する方法でした。

ステップ1-次のように、Hiveテーブルから別のテーブルにデータをロードしました

TestHiveTableCSVが存在する場合はドロップテーブル。 CREATE TABLE TestHiveTableCSV行フォーマット '、'で終了するフィールドの区切り、 '\ n'で終了する行、SELECT列リストから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

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
1
AngryCoder

Windowsから実行する場合は、Python script hivehoney を使用して、テーブルデータをローカルCSVファイルに抽出できます。

そうなる:

  • 要塞ホストにログインします。
  • pbrun。
  • kinit。
  • ビーライン(クエリを使用)。
  • エコーをビーラインから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
1
Alex B

以下は、Hiveテーブルデータをヘッダー付きの単一の名前付きCSVファイルとしてHDFSにエクスポートするために使用するエンドツーエンドソリューションです。
(1つの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
0
Gene M