2012-01-27 21 views
12

Voglio creare una tabella Hive in cui i file di testo di input vengono spostati su più sottodirectory in hdf. Così esempio ho in HDFS:Hive: creazione di tabelle con più file con più directory

/testdata/user/Jan/part-0001 
    /testdata/user/Feb/part-0001 
    /testdata/user/Mar/part-0001 
and so on... 

Se voglio creare un utente tavolo in alveare, ma hanno che sia in grado di attraversare le sottodirectory di utente, può che essere fatto? Ho provato qualcosa di simile, ma non funziona;

CREATE EXTERNAL TABLE users (id int, name string) 
STORED AS TEXTFILE LOCATION '/testdata/user/*' 

ho pensato di aggiungere il carattere jolly avrebbe funzionato, ma non lo fa. Quando ho provato a non utilizzare il carattere jolly, non funziona ancora. Tuttavia, se copio i file nella directory principale dell'utente, funziona. Non c'è modo per Hive di attraversare le directory dei bambini e prendere quei file?

risposta

5

Hive utilizza sottodirectory come partizioni dei dati, così semplicemente:

CREATE EXTERNAL TABLE users (id int, name string) PARTITIONED BY (month string) 
STORED AS TEXTFILE LOCATION '/testdata/user/' 

Questo dovrebbe farlo per voi.

+0

Questo non ha funzionato. In realtà, avrei dovuto dire che sto eseguendo CDH3u1 adesso. – user706794

+2

Definire "Non ha funzionato". Vorrei anche ricordare che sarebbe necessario cambiare i nomi delle directory in mese = gennaio ecc ... –

0
CREATE EXTERNAL TABLE user (id int, name string); 
LOAD DATA INPATH "/testdata/user/*/*" INTO TABLE users; 
+0

Questo non ha funzionato. In realtà, dovrei menzionarlo su CDH3u1 adesso. – user706794

+0

non ha funzionato per me in CDH5.7 – voldy

17

È possibile creare una tabella esterna, quindi aggiungere sottocartelle come partizioni.

CREATE EXTERNAL TABLE test (id BIGINT) PARTITIONED BY (yymmdd STRING); 
ALTER TABLE test ADD PARTITION (yymmdd = '20120921') LOCATION 'loc1'; 
ALTER TABLE test ADD PARTITION (yymmdd = '20120922') LOCATION 'loc2'; 
+0

Questa è una risposta fantastica! Sì, hai il fastidio di dover aggiornare la tabella ogni volta che c'è una nuova directory di dati (una volta al giorno nel mio caso). Ma funziona perfettamente. –

+0

Questa è anche una delle cose interessanti su come Hive memorizza i dati. Con i dati memorizzati in questo modo e rappresentati come partizioni, i dati della partizione diventano una colonna virtuale. Ciò significa che quando si esegue una query in un modo che vincola i risultati a un sottoinsieme di date (in questo caso), Hive deve solo eseguire la ricerca in alcuni punti anziché eseguire la scansione dell'intero set di dati per la risposta. – agentv

+0

Questo dovrebbe essere selezionato come risposta accettata - risponde perfettamente alla domanda. Anche tu mi hai aiutato, quindi grazie per aver risposto! –

5

Ho finito per utilizzare uno script di shell come di seguito per un caso d'uso in cui le sottodirectory non sono note a priori.

#!/bin/bash 
hive -e "CREATE EXTERNAL TABLE users (id int, name string) PARTITIONED BY (month string) STORED AS TEXTFILE LOCATION '/testdata/user/'; " 

hscript="" 

for part in `hadoop fs -ls /testdata/user/ | grep -v -P "^Found"|grep -o -P "[a-zA-Z]{3}$"`; 
do 

echo $part 
tmp="ALTER TABLE users ADD PARTITION(month='$part');" 
hscript=$hscript$tmp 
done; 

hive -e "$hscript"