मैं CSV को HiveQL क्वेरी के परिणामों का उत्पादन कैसे करूँ?


81

हम CSV फ़ाइल में हाइव क्वेरी के परिणाम डालना चाहते हैं। मुझे लगा कि कमांड को इस तरह दिखना चाहिए:

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

जब मैं इसे चलाता हूं, तो यह कहती है कि यह सफलतापूर्वक पूरा हो गया है लेकिन मैं कभी फ़ाइल नहीं ढूंढ सकता। मुझे यह फ़ाइल कैसे मिलनी चाहिए या क्या मुझे डेटा को अलग तरीके से निकालना चाहिए?

जवाबों:


146

यद्यपि INSERT OVERWRITEहाइव से डेटा प्राप्त करने के लिए इसका उपयोग करना संभव है , यह आपके विशेष मामले के लिए सबसे अच्छा तरीका नहीं हो सकता है। पहले मुझे समझाते हैं कि क्या INSERT OVERWRITEकरता है, फिर मैं हाइव तालिकाओं से tsv फ़ाइलों को प्राप्त करने के लिए उपयोग की जाने वाली विधि का वर्णन करूँगा।

मैनुअल के अनुसार , आपकी क्वेरी HDFS में एक निर्देशिका में डेटा संग्रहीत करेगी। प्रारूप csv नहीं होगा।

फाइलसिस्टम के लिए लिखे गए डेटा को ^ ए द्वारा अलग किए गए स्तंभों के साथ पाठ के रूप में क्रमबद्ध किया जाता है और न्यूलाइन्स द्वारा अलग की गई पंक्तियाँ। यदि कोई भी स्तंभ आदिम प्रकार के नहीं हैं, तो उन स्तंभों को 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 -e 'select books from table' > /home/lvermeer/temp.tsv

वह मुझे एक टैब-अलग फ़ाइल देता है जिसका मैं उपयोग कर सकता हूं। आशा है कि आप के लिए भी उपयोगी है।

इस पैच -3682 के आधार पर , मुझे संदेह है कि हाइव 0.11 का उपयोग करते समय एक बेहतर समाधान उपलब्ध है, लेकिन मैं स्वयं इसका परीक्षण करने में असमर्थ हूं। नए सिंटैक्स को निम्नलिखित की अनुमति देनी चाहिए।

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

उम्मीद है की वो मदद करदे।


2
क्या आपको पता है कि स्थानीय और पाइपिंग को सम्मिलित करने के बीच कोई प्रदर्शन अंतर है, जिस पर अनुमानित मात्रा में यह एक मुद्दा बन सकता है, साथ ही, पाइपिंग गारंटी आपको एक फ़ाइल मिलेगी, क्योंकि दूसरा दृष्टिकोण हमें एक निर्देशिका देता है, जो संभवतः हमें बाद में विलय करने की आवश्यकता है
fd8s0

क्या एचडीएफएस में डेटा को अनुक्रम फ़ाइल प्रारूप के रूप में निर्यात करना संभव है?
नागेश्वरन

1
मैंने समाधान (पैच -3682) की कोशिश की और यह मेरे लिए अच्छा काम किया - सिवाय इसके कि किसी कारण से आउटपुट फाइल में हेडर शामिल नहीं थे। ध्यान दें कि मैंने hive.cli.print.header = true सेट किया है; मेरे .hiverc में इसके लायक यह है कि हेडर टर्मिनल के बजाय मुद्रित हो गया (जो स्पष्ट रूप से वह नहीं था जो मैं चाहता था)।
पीटर कॉगन

@ lukas-vermeer, जब आप "INSERT OVERWRITE" विधि का उपयोग करके तालिका बनाते हैं, तो हेडर जानकारी खो जाती है। क्या हेडर की जानकारी प्राप्त करने का कोई तरीका है?
ML_Passion

हाय लुकास, आपने हूप फाइल सिस्टम में अपने शेल को कैसे काम किया?
नोटिलास

23

यदि आप एक CSV फ़ाइल चाहते हैं तो आप लुकास के समाधानों को इस प्रकार संशोधित कर सकते हैं (यह मानते हुए कि आप एक लिनक्स बॉक्स पर हैं):

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

4
इसके लिए धन्यवाद। मैं एक भिन्नता का उपयोग कर रहा हूं, लेकिन यह बहुत अच्छी तरह से काम करता है। कृपया ध्यान दें कि यह कॉमा-सीमांकित आउटपुट करेगा, जरूरी नहीं कि कुछ लोग सीएसवी के रूप में क्या सोचते हैं। CSV में आमतौर पर कॉमा के साथ डेटा को संभालने के लिए कुछ प्रारूपण होते हैं (जैसे डबल-कोट्स के साथ रैप डेटा, और डबल-कोट्स के साथ डेटा के लिए डबल-डबल-उद्धरण)। यह उल्लेख करते हुए कि "--hiveconf hive.cli.print.header = True" पैरामीटर को जोड़ने से आउटपुट में आपके हेडर भी मिलेंगे।
18

यह सबसे साफ समाधान है
दत्ता

1
यह मेरे लिए उदाहरण के लिए विफल रहा, एक तिथि समय स्ट्रिंग जिसमें दिनांक और समय के बीच एक स्थान था।
आइज़िस्टर

@williaster sed 's / \ t \ + /, / g' को इस समस्या के लिए मदद करनी चाहिए।
सुधाकर चव्हाण

अगर tsv में वह पाठ है जिसमें अल्पविराम होता है तो यह काम नहीं करेगा। (क्योंकि निर्विवाद निर्दोष स्ट्रिंग अल्पविराम को विभाजक के रूप में माना जाएगा)
yahiaelgamal

4

क्वेरी के परिणामों वाली फ़ाइलों के साथ HDFS में निर्देशिका बनाने के लिए आपको CREATE TABLE AS SELECT (CTAS) स्टेटमेंट का उपयोग करना चाहिए। उसके बाद आपको उन फ़ाइलों को एचडीएफएस से अपनी नियमित डिस्क पर निर्यात करना होगा और उन्हें एक ही फाइल में मर्ज करना होगा।

आपको CSV में सीमांकित फ़ाइल को '\ 001' से परिवर्तित करने के लिए कुछ चालबाजी भी करनी पड़ सकती है। आप एक कस्टम CSV सर्ड का उपयोग कर सकते हैं या निकाले गए फ़ाइल को पोस्टप्रोसेस कर सकते हैं।


यह दृष्टिकोण सबसे अच्छा है अगर कोई बाद में ओझी पाइपलाइन चरण में आउटपुट का उपयोग करना चाहता है।
सेरड

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 का उपयोग कर रहे हैं तो यह काफी सरल है। बस HUE में Hive एडिटर पर जाएं, अपनी हाइव क्वेरी को निष्पादित करें, फिर परिणाम फ़ाइल को स्थानीय रूप से XLS या CSV के रूप में सहेजें, या आप परिणाम फ़ाइल को HDFS में सहेज सकते हैं।


3

मैं इसी तरह के समाधान की तलाश कर रहा था, लेकिन यहां उल्लिखित काम नहीं करेंगे। मेरे डेटा में व्हाट्सएप (स्पेस, न्यूलाइन, टैब) वर्ण और कॉमा के सभी रूपांतर थे।

स्तंभ डेटा tsv को सुरक्षित बनाने के लिए, मैंने स्तंभ डेटा में सभी \ t वर्णों को एक स्थान के साथ बदल दिया, और एक 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)")'

इसने पूरी तरह से वैध सीएसवी बनाया। आशा है कि यह उन लोगों की मदद करता है जो इस समाधान की तलाश में आते हैं।


1
यह 2016 है और हमें अभी भी ऐसा करने के लिए हुप्स से कूदना होगा? मैंने पाया कि श्रावस्टर का समाधान अब तक का सबसे अच्छा, सबसे सुरुचिपूर्ण समाधान है।
जोश

आपने कॉलम डेटा में सभी \ t वर्णों को कैसे प्रतिस्थापित किया? क्या आपने इसे क्वेरी में संबोधित किया या इसके लिए एक अलग दृश्य बनाया?
नरेश एस

@ नरेश, देर से प्रतिक्रिया के लिए क्षमा करें। हां, कॉलम को रिक्त स्थान के साथ टैब को बदलने के लिए हाइव में संभाला गया था या यदि वे आवश्यक हैं, तो आप एक विकल्प जैसे <: टैब>, या उन पंक्तियों के साथ कुछ बदल सकते हैं
18:18

@ सुनसान, प्रतिक्रिया के लिए धन्यवाद। मुझे लगता है कि हमें सभी स्ट्रिंग कॉलमों के लिए रेगेक्स रिप्लेस का उपयोग करने की आवश्यकता है और यह बोझिल होगा यदि हमारे पास बड़ी संख्या में कॉलम्स> 100 है। क्या इस तरह के मामले का कोई त्वरित समाधान है
नरेश एस

@ नरेश, दुर्भाग्यवश आपके विभाजन में डालने से पहले डेटा को साफ करने का एकमात्र उपाय है। अन्यथा आपको इसे उन सभी स्ट्रिंग कॉलमों के लिए चयन करते समय करना होगा जिनमें टैब वर्ण हो सकते हैं
4:18

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

यह सबसे ज्यादा सीएसवी फ्रेंडली तरीका है जो मैंने HiveQL के परिणामों का उत्पादन करने के लिए पाया।
आपको डेटा को प्रारूपित करने के लिए किसी grep या sed कमांड की आवश्यकता नहीं है, इसके बजाय हाइव इसका समर्थन करता है, बस outputformat के अतिरिक्त टैग को जोड़ने की आवश्यकता है।

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

2

मेरे पास एक समान मुद्दा था और इस तरह मैं इसे संबोधित करने में सक्षम था।

चरण 1 - हाइव तालिका से डेटा को एक अन्य तालिका में निम्नानुसार लोड किया

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" है। अजगर भाषा में, यह " \x01" है।

जब मैं सीमांकक को बदलना चाहता हूं, तो मैं एसक्यूएल का उपयोग करता हूं:

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

ऊपर रे के उत्तर के समान, हॉर्टनवर्क्स डेटा प्लेटफ़ॉर्म में हाइव व्यू 2.0 भी आपको हाइव क्वेरी चलाने और फिर आउटपुट को सीएसवी के रूप में सहेजने की अनुमति देता है।


0

यदि आप इसे विंडोज से कर रहे हैं, तो आप स्थानीय CSV फ़ाइल में तालिका डेटा निकालने के लिए पायथन स्क्रिप्ट हाइवेनी का उपयोग कर सकते हैं ।

यह:

  1. गढ़ होस्ट करने के लिए लॉग इन करें।
  2. एक प्रकार का पौधा
  3. परिजन
  4. बीलाइन (आपकी क्वेरी के साथ)।
  5. विंडोज पर एक फाइल को बीलाइन से इको सेव करें।

इसे इस तरह निष्पादित करें:

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;

मेरे मामले में, अस्थायी फ़ोल्डर के तहत उत्पन्न डेटा 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

यहां डिफ्लेट फाइलों को अनजिप करने और सब कुछ एक सीएसवी फाइल में डालने की आज्ञा है:

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) का चयन करें। >> SAMPLE_Data.csv


0

यह शेल कमांड output.txtकॉलम में बिना हेडर के आउटपुट फॉर्मेट को प्रिंट करता है ।

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

0

कमांड का उपयोग करें:

hive -e "का उपयोग करें [database_name]; * से चुनें [table_name] सीमा 10;" > /पथ / //ile/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 Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.