Як вивести результати запиту HiveQL у CSV?


81

ми хотіли б розмістити результати запиту Hive у файл CSV. Я вважав, що команда повинна виглядати так:

insert overwrite directory '/home/output.csv' select books from table;

Коли я запускаю його, він повідомляє, що він завершився успішно, але я ніколи не можу знайти файл. Як мені знайти цей файл чи я повинен витягувати дані іншим способом?

Відповіді:


146

Незважаючи на те, що це можна використовувати INSERT OVERWRITEдля виведення даних з вулика, це може бути не найкращим методом для вашого конкретного випадку. Спочатку дозвольте пояснити, що INSERT OVERWRITEце робить, потім я опишу метод, який я використовую для отримання файлів tsv з таблиць Hive.

Згідно з посібником , ваш запит зберігатиме дані у каталозі у HDFS. Формат не буде CSV.

Дані, записані у файлову систему, серіалізуються як текст із стовпцями, розділеними ^ A, та рядками, розділеними новими рядками. Якщо будь-який із стовпців не має примітивний тип, тоді ці стовпці серіалізуються у форматі JSON.

Невелике внесення змін (додавання LOCALключового слова) збереже дані в локальному каталозі.

INSERT OVERWRITE LOCAL DIRECTORY '/home/lvermeer/temp' select books from table;

Коли я запускаю подібний запит, ось як виглядає результат.

[lvermeer@hadoop temp]$ ll
total 4
-rwxr-xr-x 1 lvermeer users 811 Aug  9 09:21 000000_0
[lvermeer@hadoop temp]$ head 000000_0 
"row1""col1"1234"col3"1234FALSE
"row2""col1"5678"col3"5678TRUE

Особисто я зазвичай запускаю свій запит безпосередньо через Hive в командному рядку для такого роду речей і передаю його в локальний файл так:

hive -e 'select books from table' > /home/lvermeer/temp.tsv

Це дає мені файл, відокремлений табуляцією, який я можу використовувати. Сподіваюся, це корисно і вам.

Виходячи з цього патча-3682 , я підозрюю, що при використанні Hive 0.11 доступне краще рішення, але я не можу перевірити це сам. Новий синтаксис повинен дозволити наступне.

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

Сподіваюся, що це допомагає.


2
чи знаєте ви якусь різницю в продуктивності між вставкою локального перезапису та конвеєром, при якому приблизному обсязі це може стати проблемою, також трубопровід гарантує отримання одного файлу, оскільки інший підхід дає нам каталог, який потенційно нам потрібно об’єднати згодом
fd8s0

Чи можна експортувати дані у форматі HDFS як формат файлу послідовності?
Nageswaran,

1
Я спробував рішення (patch-3682), і воно у мене спрацювало добре - за винятком того, що у вихідному файлі чомусь не було заголовків. Зверніть увагу, що я встановив hive.cli.print.header = true; в моєму .hiverc. Для чого варто заголовки надрукували на терміналі (що, очевидно, не те, що я хотів).
Пітер Коган

@ lukas-vermeer, коли ви створюєте таблицю методом "INSERT OVERWRITE", інформація заголовка втрачається. Чи є спосіб отримати інформацію про заголовок?
ML_Passion

Привіт Лукас, як ти змусив твою оболонку працювати у файловій системі hadoop?
notilas

23

Якщо вам потрібен файл CSV, тоді ви можете змінити рішення Лукаса наступним чином (припускаючи, що ви перебуваєте у вікні Linux):

hive -e 'select books from table' | sed 's/[[:space:]]\+/,/g' > /home/lvermeer/temp.csv

4
Дякую за це. Я використовую варіацію, але вона працює дуже добре. Будь ласка, зверніть увагу, що це буде виводити з комою, не обов'язково те, що деякі люди вважають CSV. CSV, як правило, має деяке форматування для обробки даних із комами (наприклад, обтікання даних подвійними лапками та подвійне подвоєння лапок для даних із подвійними лапками). Варто згадати, що додавання параметра "--hiveconf hive.cli.print.header = True" також отримає ваші заголовки у вихідних даних.
jatal

Це найчистіше рішення
Dutta

1
Для мене це не вдалося, наприклад, рядок дати, який мав проміжок між датою та часом.
williaster

@williaster sed 's / \ t \ + /, / g', це має допомогти у вирішенні цієї проблеми.
Судхакар Чаван,

Це не спрацювало б, якщо у tsv є текст, який містить коми. (оскільки невинні
коди без

4

Вам слід використовувати оператор CREATE TABLE AS SELECT (CTAS), щоб створити каталог у HDFS з файлами, що містять результати запиту. Після цього вам доведеться експортувати ці файли з HDFS на ваш звичайний диск і об'єднати їх в один файл.

Можливо, вам доведеться виконати деякі хитрощі, щоб перетворити файли з \ \ 001 з роздільником у CSV. Ви можете використовувати власний CSV SerDe або обробити витягнутий файл.


Цей підхід найкращий, якщо ви хочете використовувати вихідні дані на наступному кроці трубопроводу oozie.
сертифікат

4

Ви можете використовувати INSERT…… DIRECTORY, як у цьому прикладі:

INSERT OVERWRITE LOCAL DIRECTORY '/tmp/ca_employees'
SELECT name, salary, address
FROM employees
WHERE se.state = 'CA';

OVERWRITEі LOCALмають такі ж інтерпретації, як і раніше, і шляхи інтерпретуються відповідно до звичайних правил. Буде записано один або кілька файлів /tmp/ca_employees, залежно від кількості викликаних редукторів.


3

Якщо ви використовуєте HUE, це теж досить просто. Просто перейдіть до редактора Hive в HUE, виконайте запит на вулик, а потім збережіть файл результатів локально як XLS або CSV, або ви можете зберегти файл результатів у HDFS.


3

Я шукав подібне рішення, але згадані тут не спрацюють. У моїх даних були всі варіанти пробілів (пробіл, новий рядок, вкладка), символи та коми.

Щоб зробити дані стовпців tsv безпечними, я замінив усі символи \ t у даних стовпця пробілом і виконав команду python у командному рядку для створення CSV-файлу, як показано нижче:

hive -e 'tab_replaced_hql_query' |  python -c 'exec("import sys;import csv;reader = csv.reader(sys.stdin, dialect=csv.excel_tab);writer = csv.writer(sys.stdout, dialect=csv.excel)\nfor row in reader: writer.writerow(row)")'

Це створило цілком дійсний CSV. Сподіваюся, це допоможе тим, хто прийде шукати це рішення.


1
Це 2016 рік, і нам все одно доведеться перестрибнути обручі, щоб зробити це? Я знайшов рішення shravster найкращим, найелегантнішим рішенням на сьогодні.
Джош

Як ви замінили всі символи \ t у даних стовпця? Ви зверталися до нього у запиті чи створювали для нього окреме представлення?
Naresh S

@NareshS, вибачте за пізню відповідь. Так, стовпці оброблялися у вулику, щоб замінити вкладки пробілами, або якщо вони є важливими, ви можете замінити на заміну, наприклад <: tab>, або щось подібне до цих рядків
sisanared

@sisanared, Дякую за відповідь. Я бачу, що нам потрібно використовувати заміну регулярних виразів для всіх стовпців рядків, і це було б громіздко, якщо б у нас була таблиця з великою кількістю colums> 100. Чи є швидке рішення для такого випадку
Naresh S

@NareshS, на жаль, єдиним іншим рішенням є очищення даних перед розміщенням їх у своїх розділах. В іншому випадку вам доведеться це зробити, виконуючи вибір для всіх стовпців рядків, які можуть містити символи табуляції
sisanared

3

Ви можете використовувати функцію рядка вулика CONCAT_WS( string delimiter, string str1, string str2...strn )

наприклад:

hive -e 'select CONCAT_WS(',',cola,colb,colc...,coln) from Mytable' > /home/user/Mycsv.csv

3

Це найбільш зручний для CSV спосіб, який я знайшов для виведення результатів HiveQL.
Вам не потрібні команди grep або sed для форматування даних, натомість вулик їх підтримує, потрібно лише додати додатковий тег outputformat.

hive --outputformat=csv2 -e 'select * from <table_name> limit 20' > /path/toStore/data/results.csv

2

У мене була подібна проблема, і ось як я міг її вирішити.

Крок 1 - Завантажено дані з таблиці Hive в іншу таблицю наступним чином

DROP TABLE IF EXISTS TestHiveTableCSV;
CREATE TABLE TestHiveTableCSV 
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n' AS
SELECT Column List FROM TestHiveTable;

Крок 2 - Скопійовано крапку зі складу Вулля на нове місце з відповідним розширенням

Start-AzureStorageBlobCopy
-DestContext $destContext 
-SrcContainer "Source Container"
-SrcBlob "hive/warehouse/TestHiveTableCSV/000000_0"
-DestContainer "Destination Container"
-DestBlob "CSV/TestHiveTable.csv"

2
hive  --outputformat=csv2 -e "select * from yourtable" > my_file.csv

або

hive  --outputformat=csv2 -e "select * from yourtable" > [your_path]/file_name.csv

Для tsv просто змініть csv на tsv у наведених вище запитах та запустіть свої запити


1

Типовим роздільником є ​​" ^A". Мовою python це "\x01 ".

Коли я хочу змінити роздільник, я використовую SQL як:

SELECT col1, delimiter, col2, delimiter, col3, ..., FROM table

Потім розгляньте роздільник + " ^A" як новий роздільник.


1

Я пробував різні варіанти, але це було б одне з найпростіших рішень для Python Pandas:

hive -e 'select books from table' | grep "|" ' > temp.csv

df=pd.read_csv("temp.csv",sep='|')

Ви також можете використовувати tr "|" ","для перетворення "|" до ","


0

Подібно до відповіді Рея вище, Hive View 2.0 в Hortonworks Data Platform також дозволяє запускати запит Hive, а потім зберігати результати як csv.


0

Якщо ви робите це з Windows, ви можете використовувати скрипт Python hivehoney для вилучення даних таблиці в локальний файл CSV.

Це буде:

  1. Увійдіть на хост бастіону.
  2. пбрун.
  3. кініт.
  4. білайн (з вашим запитом).
  5. Збережіть ехо з білайн у файл у 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

0

Просто, щоб охопити більше наступних кроків після запуску запиту: INSERT OVERWRITE LOCAL DIRECTORY '/home/lvermeer/temp' ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' select books from table;

У моєму випадку згенеровані дані у папці temp мають deflateформат, і це виглядає так:

$ ls
000000_0.deflate  
000001_0.deflate  
000002_0.deflate  
000003_0.deflate  
000004_0.deflate  
000005_0.deflate  
000006_0.deflate  
000007_0.deflate

Ось команда для розпакування файлів дефляції та розміщення всього в одному файлі csv:

hadoop fs -text "file:///home/lvermeer/temp/*" > /home/lvermeer/result.csv

0

Я можу запізнитися з цим, але допоміг би відповісти:

echo "COL_NAME1 | COL_NAME2 | COL_NAME3 | COL_NAME4"> SAMPLE_Data.csv hive -e 'виберіть окремий конкат (COL_1, "|", COL_2, "|", COL_3, "|", COL_4) із таблиці_Name, де пункт, якщо потрібно;' >> SAMPLE_Data.csv


0

Ця команда оболонки друкує вихідний формат у CSV output.txtбез заголовків стовпців.

$ hive --outputformat=csv2 -f 'hivedatascript.hql' --hiveconf hive.cli.print.header=false > output.txt

0

Використовуйте команду:

hive -e "використовувати [ім'я_бази даних]; вибрати * з [ім'я_таблиці] ОБМЕЖЕННЯ 10;" > /path/to/file/my_file_name.csv

У мене був величезний набір даних , деталі якого я намагався організувати та визначити типи атак та кількість кожного типу. Приклад, який я використав на своїй практиці, яка працювала (і мала трохи більше деталей), виглядає приблизно так:

hive -e "use DataAnalysis;
select attack_cat, 
case when attack_cat == 'Backdoor' then 'Backdoors' 
when length(attack_cat) == 0 then 'Normal' 
when attack_cat == 'Backdoors' then 'Backdoors' 
when attack_cat == 'Fuzzers' then 'Fuzzers' 
when attack_cat == 'Generic' then 'Generic' 
when attack_cat == 'Reconnaissance' then 'Reconnaissance' 
when attack_cat == 'Shellcode' then 'Shellcode' 
when attack_cat == 'Worms' then 'Worms' 
when attack_cat == 'Analysis' then 'Analysis' 
when attack_cat == 'DoS' then 'DoS' 
when attack_cat == 'Exploits' then 'Exploits' 
when trim(attack_cat) == 'Fuzzers' then 'Fuzzers' 
when trim(attack_cat) == 'Shellcode' then 'Shellcode' 
when trim(attack_cat) == 'Reconnaissance' then 'Reconnaissance' end,
count(*) from actualattacks group by attack_cat;">/root/data/output/results2.csv
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.