16

Sto cercando di eseguire un'istruzione inserto con il mio HiveContext, in questo modo:"INSERT INTO ..." con SparkSQL HiveContext

hiveContext.sql('insert into my_table (id, score) values (1, 10)') 

Il 1.5.2 Spark SQL Documentation non afferma esplicitamente se questa è supportata o meno, sebbene supporti "l'inserimento della partizione dinamica".

Questo porta ad una traccia dello stack come

AnalysisException: 
Unsupported language features in query: insert into my_table (id, score) values (1, 10) 
TOK_QUERY 0, 0,20, 0 
    TOK_FROM 0, -1,20, 0 
    TOK_VIRTUAL_TABLE 0, -1,20, 0 
     TOK_VIRTUAL_TABREF 0, -1,-1, 0 
     TOK_ANONYMOUS 0, -1,-1, 0 
     TOK_VALUES_TABLE 1, 13,20, 41 
     TOK_VALUE_ROW 1, 15,20, 41 
      1 1, 16,16, 41 
      10 1, 19,19, 44 
    TOK_INSERT 1, 0,-1, 12 
    TOK_INSERT_INTO 1, 0,11, 12 
     TOK_TAB 1, 4,4, 12 
     TOK_TABNAME 1, 4,4, 12 
      my_table 1, 4,4, 12 
     TOK_TABCOLNAME 1, 7,10, 22 
     id 1, 7,7, 22 
     score 1, 10,10, 26 
    TOK_SELECT 0, -1,-1, 0 
     TOK_SELEXPR 0, -1,-1, 0 
     TOK_ALLCOLREF 0, -1,-1, 0 

scala.NotImplementedError: No parse rules for: 
TOK_VIRTUAL_TABLE 0, -1,20, 0 
    TOK_VIRTUAL_TABREF 0, -1,-1, 0 
    TOK_ANONYMOUS 0, -1,-1, 0 
    TOK_VALUES_TABLE 1, 13,20, 41 
    TOK_VALUE_ROW 1, 15,20, 41 
     1 1, 16,16, 41 
     10 1, 19,19, 44 

C'è un altro modo per inserire un tavolo alveare che è supportati?

risposta

17

I dati possono essere aggiunti a una tabella Hive utilizzando la modalità append in DataFrameWriter.

data = hc.sql("select 1 as id, 10 as score") 
data.write.mode("append").saveAsTable("my_table") 

Questo dà lo stesso risultato di un inserto.

+0

Voglio scriverlo su un tavolo esistente. Come lo posso fare? Sto usando Spark 1.1.0, che non ha il metodo di scrittura. cosa posso fare in quel caso? –

+0

Ti piacerebbe accettare la risposta per favore così possiamo chiudere questa domanda?:) – eliasah

+0

@eliasah Ho fatto un'appendice nel metodo che hai specificato, ma quando faccio una selezione * sulla tabella dell'alveare sto ottenendo le righe aggiunte in alto, invece di essere nella parte inferiore – User12345

6

Ho avuto lo stesso problema (Spark 1.5.1) e ho provato diverse versioni.

Attribuite

sqlContext.sql("create table my_table(id int, score int)") 

Le uniche versioni che hanno lavorato si presentava così:

sqlContext.sql("insert into table my_table select t.* from (select 1, 10) t") 
sqlContext.sql("insert into  my_table select t.* from (select 2, 20) t") 
+0

Come aggiungere variabili nella query? – yAsH

+0

Anche una soluzione valida per funzionare nel caso in cui si abbia una tabella di origine con la stessa chiave della tabella di destinazione. Funziona nella scintilla 1.5 –

0

provare questo hiveContext.sql("insert into table my_table select 1, 10") se non hai modificare la modalità di partizione dinamica a nonstrict, devi fare questo hiveCtx.setConf("hive.exec.dynamic.partition.mode", "nonstrict")

+3

Perché l'OP deve "provare questo codice"? Una ** buona risposta ** avrà sempre una spiegazione di cosa è stato fatto e perché è stato fatto in questo modo, non solo per l'OP ma per i futuri visitatori di SO. –

+0

Inoltre, non funziona ... vedi la risposta di Berylium qui sotto, funziona –

4

La risposta accettata saveAsTable non riesce per me con un AnalysisException (non capisco perché). Quello che funziona per me è:

data = hc.sql("select 1 as id, 10 as score") 
data.write.mode("append").insertInto("my_table") 

Sto usando Spark v2.1.0.

1

Si è tentato di eseguire qualcosa che il formato del file di dati non può, quindi l'eccezione Unsupported language features in query.

Molti formati di file di dati sono in scrittura una volta e non supportano l'operazione ACID.

L'ORC di Apache supporta il funzionamento ACID se necessario.

Invece, è possibile utilizzare la partizione per dividere i dati in cartelle (/ dati/anno = 2017/mese = 10 ....), qui è possibile aggiungere/inserire dati nel proprio data lake.

0

Quando si esegue questa operazione prima volta

$data.write.mode("append").saveAsTable("my_table") 

è necessario sostituire "append" con "overwrite", Quindi, è possibile utilizzare "append".