Come impostare le variabili negli script HIVE


102

Sto cercando l'equivalente SQL di SET varname = valuein Hive QL

So di poter fare qualcosa del genere:

SET CURRENT_DATE = '2012-09-16';
SELECT * FROM foo WHERE day >= @CURRENT_DATE

Ma poi ottengo questo errore:

il carattere "@" non è supportato qui


Sfortunatamente, non esiste un modo sicuro per impostare una variabile stringa perché se qualcuno esegue la query senza impostare la variabile, la stringa utilizzerà semplicemente la chiamata della variabile come stringa. :(
combinatore

Risposte:


201

È necessario utilizzare lo speciale hiveconf per la sostituzione delle variabili. per esempio

hive> set CURRENT_DATE='2012-09-16';
hive> select * from foo where day >= '${hiveconf:CURRENT_DATE}'

allo stesso modo, potresti passare dalla riga di comando:

% hive -hiveconf CURRENT_DATE='2012-09-16' -f test.hql

Nota che ci sono anche env e variabili di sistema , quindi puoi fare riferimento ${env:USER}ad esempio.

Per vedere tutte le variabili disponibili, dalla riga di comando, esegui

% hive -e 'set;'

o dal prompt dell'hive, esegui

hive> set;

Aggiornamento: ho iniziato a utilizzare anche le variabili hivevar , inserendole in frammenti hql che posso includere dalla CLI di hive utilizzando il sourcecomando (o passa come opzione -i dalla riga di comando). Il vantaggio qui è che la variabile può quindi essere utilizzata con o senza il prefisso hivevar e consentire qualcosa di simile all'uso globale rispetto a quello locale.

Quindi, supponiamo di avere un po ' setup.hql che imposta una variabile tablename:

set hivevar:tablename=mytable;

quindi, posso portare in alveare:

hive> source /path/to/setup.hql;

e usa nella query:

hive> select * from ${tablename}

o

hive> select * from ${hivevar:tablename}

Potrei anche impostare un tablename "locale", che influirebbe sull'uso di $ {tablename}, ma non di $ {hivevar: tablename}

hive> set tablename=newtable;
hive> select * from ${tablename} -- uses 'newtable'

vs

hive> select * from ${hivevar:tablename} -- still uses the original 'mytable'

Probabilmente non significa molto dalla CLI, ma può avere hql in un file che utilizza il sorgente , ma impostare alcune delle variabili "localmente" da utilizzare nel resto dello script.


1
Questo è il passaggio di un parametro dalla riga di comando. Sto sviluppando query in Karmasphere e devo impostare alcuni contenuti nell'accattonaggio in modo da non codificare le date 10 volte nel mio script. È possibile qualcosa del genere?
user1678312

funziona in entrambi i modi, se lo fai set CURRENT_DATE='2012-09-16';puoi fare riferimento ad esso in seguito con${hiveconf:CURRENT_DATE}
libjack

1
Come funziona se ho più processi Hive in esecuzione contemporaneamente? Finiranno per raccogliere valori l'uno dall'altro? Nell'automazione sto costruendo un file HQL anteponendolo ad alcune istruzioni SET. Voglio essere sicuro che se invio due lavori allo stesso tempo che utilizzano gli stessi nomi di variabili, un lavoro non preleverà valori dall'altro lavoro. La semantica qui non è chiara dalla tua risposta.
MattD

5
questo funziona per me sul server Hive. Tuttavia, ho impostato alcuni test di integrazione sulla macchina locale in IntelliJ. Continuo a ricevere il seguente errore quando FAILED: ParseException line x:y cannot recognize input near '$' '{' 'hiveconf' in expression specification
provo

1
@DatabaseCoder Per quanto ne so, niente del genere funzionerà. Ogni volta che ho bisogno di qualcosa del genere, devo fare la prima query e poi passare tramite "--hiveconf"
libjack

21

La maggior parte delle risposte qui hanno suggerito di utilizzare hiveconfo lo hivevarspazio dei nomi per memorizzare la variabile. E tutte queste risposte sono corrette. Tuttavia, c'è un altro spazio dei nomi.

Ci sono tre totali namespacesdisponibili per contenere le variabili.

  1. hiveconf - hive è iniziato con questo, tutta la configurazione di hive è memorizzata come parte di questa configurazione. Inizialmente, la sostituzione delle variabili non faceva parte di hive e quando è stata introdotta, anche tutte le variabili definite dall'utente sono state memorizzate come parte di questo. Che sicuramente non è una buona idea. Quindi sono stati creati altri due spazi dei nomi.
  2. hivevar : per memorizzare le variabili utente
  3. sistema : per memorizzare le variabili di sistema.

Quindi, se si memorizza una variabile come parte di una query (ad es. Data o numero_prodotto), è necessario utilizzare lo hivevarspazio dei nomi e non lo hiveconfspazio dei nomi.

Ed è così che funziona.

hiveconf è ancora lo spazio dei nomi predefinito , quindi se non fornisci alcuno spazio dei nomi memorizzerà la tua variabile nello spazio dei nomi hiveconf.

Tuttavia, quando si tratta di fare riferimento a una variabile, non è vero. Per impostazione predefinita, si riferisce allo spazio dei nomi hivevar . Confuso, vero? Può diventare più chiaro con il seguente esempio.

Se non fornisci lo spazio dei nomi come indicato di seguito, la variabile varverrà archiviata nello hiveconfspazio dei nomi.

set var="default_namespace";

Quindi, per accedervi è necessario specificare lo hiveconf spazio dei nomi

select ${hiveconf:var};

E se non fornisci lo spazio dei nomi ti darà un errore come indicato di seguito, il motivo è che per impostazione predefinita se provi ad accedere a una variabile controlla hivevarsolo nello spazio dei nomi. E hivevarnon c'è nessuna variabile denominatavar

select ${var}; 

Abbiamo fornito esplicitamente lo hivevarspazio dei nomi

set hivevar:var="hivevar_namespace";

poiché stiamo fornendo lo spazio dei nomi, funzionerà.

select ${hivevar:var}; 

E come impostazione predefinita, lo spazio di lavoro utilizzato durante il riferimento a una variabile è hivevar, funzionerà anche quanto segue.

select ${var};

7

Hai provato a usare il simbolo del dollaro e le parentesi in questo modo:

SELECT * 
FROM foo 
WHERE day >= '${CURRENT_DATE}';

Questa è l'unica risposta funzionante per me. Le virgolette sono obbligatorie nella mia interfaccia hive ambari.
Laurens Koppenol

ci sono due cose hivevar e hiveconf- entrambe sono spiegate in dettaglio qui
Rahul Sharma


2

Una cosa da tenere presente è impostare le stringhe e poi fare riferimento a esse. Devi assicurarti che le virgolette non entrino in conflitto.

 set start_date = '2019-01-21';
 select ${hiveconf:start_date}; 

Quando si impostano le date, si fa riferimento ad esse nel codice poiché le stringhe possono entrare in conflitto. Questo non funzionerebbe con la data_inizio impostata sopra.

 '${hiveconf:start_date}'

Dobbiamo essere consapevoli di non impostare due volte le virgolette singole o doppie per le stringhe quando si fa riferimento ad esse nella query.


2

Nel caso in cui qualcuno abbia bisogno di parametrizzare la query hive tramite cli.

Ad esempio:

hive_query.sql

SELECT * FROM foo WHERE day >= '${hivevar:CURRENT_DATE}'

Ora esegui il file sql sopra da cli:

hive --hivevar CURRENT_DATE="2012-09-16" -f hive_query.sql

0

Prova questo metodo:

set t=20;
select *
from myTable
where age > '${hiveconf:t}'; 

funziona bene sulla mia piattaforma.


0

Puoi esportare la variabile nello script di shell export CURRENT_DATE = "2012-09-16"

Quindi in hiveql ti piace SELECT * FROM foo WHERE day> = '$ {env: CURRENT_DATE}'


-7

Puoi memorizzare l'output di un'altra query in una variabile e quest'ultima puoi usare lo stesso nel tuo codice:

set var=select count(*) from My_table;
${hiveconf:var};

Hai sbagliato, seleziona count (*) da My_table; verrà archiviato in var .
Ilya Bystrov
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.