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?
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
.
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.
Ç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
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
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é.
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
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.
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
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
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
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
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:
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
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