web-dev-qa-db-fra.com

Comment exporter une table Hive dans un fichier CSV?

J'ai utilisé cette requête Hive pour exporter une table dans un fichier CSV.

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

Le fichier généré '000000_0' n'a pas de séparateur de virgule

Est-ce la bonne façon de générer un fichier CSV? Si non, s'il vous plaît laissez-moi savoir comment puis-je générer le fichier CSV?

44
Dunith Dhanushka

ou utiliser cette

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

Vous pouvez également spécifier la propriété set Hive.cli.print.header=true avant la SELECT pour vous assurer que l'en-tête, ainsi que les données, sont créés et copiés dans un fichier. Par exemple:

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

Si vous ne souhaitez pas écrire dans le système de fichiers local, redirigez la sortie de la commande sed dans HDFS à l'aide de la commande hadoop fs -put.

46
user1922900

Si vous utilisez Hive 11 ou une version supérieure, vous pouvez utiliser l'instruction INSERT avec le mot clé LOCAL.

Exemple:

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

Notez que cela peut créer plusieurs fichiers et que vous souhaiterez peut-être les concaténer côté client une fois l'exportation terminée.

Cette approche vous évite d'avoir à vous soucier du format des tables source, vous pouvez exporter en fonction de requêtes SQL arbitraires et sélectionner vos propres délimiteurs et formats de sortie.

45
Carter Shanklin

Ça devrait marcher pour vous

  • onglet séparé

    Hive -e 'select * from some_table' > /home/yourfile.tsv
  • séparées par des virgules

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

Vous ne pouvez pas avoir de délimiteur pour la sortie de la requête, après avoir généré le rapport (comme vous l'avez fait).

vous pouvez changer le délimiteur en virgule.

Il est livré avec le délimiteur par défaut \001 (caractère non divisible).

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

cochez cette aussi

21
Balaswamy Vaddeman

Les versions récentes de Hive sont livrées avec cette fonctionnalité.

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

de cette façon, vous pouvez choisir votre propre délimiteur et nom de fichier . Soyez juste prudent avec le "ÉCRASER", il essaiera de tout supprimer du dossier mentionné.

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

est la bonne réponse.

Si le nombre d'enregistrements est vraiment important, basé sur le nombre de fichiers générés 

la commande suivante ne donnerait qu'un résultat partiel.

Hive -e 'select * from some_table' > /home/yourfile.csv
6
Jsim

Le script suivant devrait fonctionner pour vous:

#!/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

J'ai utilisé limit 100 pour limiter la taille des données car j'avais un énorme tableau, mais vous pouvez le supprimer pour exporter l'intégralité du tableau.

4
HISI

J'ai utilisé linux Shell Piping + Perl simple pour convertir la sortie générée par Hive de tsv en csv.

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

(J'ai reçu la regex Perl mise à jour de quelqu'un dans stackoverflow il y a quelque temps)

Le résultat sera comme un csv normal:

"col1","col2","col3"... et ainsi de suite

4
Firman Gautama

Ici, en utilisant le répertoire d’entrepôt Hive, vous pouvez exporter des données au lieu de la table Hive. donne d’abord le chemin d’entrepôt Hive et après le chemin local où vous voulez stocker le fichier .csv Cette commande est décrite ci-dessous: -

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

Il existe des moyens de modifier le délimiteur par défaut, comme le montrent d'autres réponses.

Il existe également des moyens de convertir la sortie brute en csv avec quelques scripts bash. Il y a 3 délimiteurs à considérer cependant, pas seulement\001. Les choses se compliquent un peu lorsque votre table Hive contient maps

J'ai écrit un script bash qui peut gérer les 3 délimiteurs par défaut (\ 001\002 et\003) de Hive et générer un csv. Le script et quelques informations supplémentaires sont ici:

Hive Default Delimiters to CSV

Les délimiteurs par défaut de Hive sont

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

Il existe des moyens de modifier ces délimiteurs lors de l'exportation de tables, mais Parfois, vous pouvez toujours avoir besoin de le convertir en csv. 

Voici un script bash rapide pouvant gérer une exportation de base de données au format segmenté en plusieurs fichiers et possède les délimiteurs par défaut. Ce sera générer un seul fichier CSV.

On suppose que tous les segments ont la convention de dénomination 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

Plus d'explications sur the Gist

1
alex9311

J'ai eu un problème similaire et c'est ainsi que j'ai pu y remédier.

Étape 1 - Charger les données de la table Hive dans une autre table comme suit

DROP TABLE SI EXISTS TestHiveTableCSV; CREATE TABLE TestHiveTableCSV ROW FORMAT DELAMITED FIELDS TERMINATED BY ',' LIGNES TERMINÉES PAR '\ n' AS. SELECT Liste de colonnes FROM TestHiveTable;

Étape 2 - Copier le blob de l'entrepôt Hive vers le nouvel emplacement avec l'extension appropriée

Start-AzureStorageBlobCopy -DestContext $destContext -SrcContainer "conteneur source" -SrcBlob "Hive/warehouse/TestHiveTableCSV/000000_0" -DestContainer "Destination Container" ` -DestBlob "CSV/TestHiveTable.csv"

J'espère que cela t'aides!

Cordialement, Dattatrey Sindol (Datta) http://dattatreysindol.com

1
Dattatrey Sindol

Si vous le faites sous Windows, vous pouvez utiliser le script Python hivehoney pour extraire les données de la table dans un fichier CSV local.

Ce sera:

  • Connectez-vous à l'hôte bastion. 
  • pbrun. 
  • kinit. 
  • beeline (avec votre requête). 
  • Enregistrez Echo de beeline dans un fichier sous Windows.

Exécutez-le comme ceci:

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

Les solutions aux problèmes sont bien mais j'ai trouvé des problèmes dans les deux:

  • Comme l'a dit Carter Shanklin, cette commande permet d'obtenir un fichier csv avec les résultats de la requête dans le chemin spécifié:

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

    Le problème avec cette solution est que le fichier csv obtenu n’aura pas d’en-têtes et créera un fichier qui n’est pas un fichier CSV (nous devons donc le renommer).

  • Comme user1922900 l'a dit, avec la commande suivante, nous obtiendrons un fichier CSV avec les résultats de la requête dans le fichier spécifié et avec des en-têtes:

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

    Avec cette solution, nous obtiendrons un fichier CSV avec les lignes de résultat de notre requête, mais avec les messages de journalisation entre ces lignes également. En guise de solution à ce problème, j'ai essayé ceci , mais sans résultat.

Donc, pour résoudre tous ces problèmes, j'ai créé un script qui exécute une liste de requêtes, crée un dossier (avec un horodatage) dans lequel il stocke les résultats, renomme les fichiers obtenus, supprime les fichiers inutiles et ajoute les en-têtes correspondants.

 #!/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
0
AngryCoder