it-swarm.com.de

spark-Datenframe in Hive speichern: Tabelle nicht lesbar, da "Parkett kein SequenceFile" ist

Ich möchte Daten in einem Spark-Datenframe (Version 1.3.0) mit PySpark in einer Hive-Tabelle speichern.

Die Dokumentation besagt:

"spark.sql.Hive.convertMetastoreParquet: Wenn der Wert auf false gesetzt ist, verwendet Spark SQL die Hive SerDe für Parketttabellen anstelle der integrierten Unterstützung."

Wenn Sie das Spark-Tutorial betrachten, scheint es, dass diese Eigenschaft gesetzt werden kann:

from pyspark.sql import HiveContext

sqlContext = HiveContext(sc)
sqlContext.sql("SET spark.sql.Hive.convertMetastoreParquet=false")

# code to create dataframe

my_dataframe.saveAsTable("my_dataframe")

Wenn ich jedoch versuche, die gespeicherte Tabelle in Hive abzufragen, wird Folgendes ausgegeben:

Hive> select * from my_dataframe;
OK
Failed with exception Java.io.IOException:Java.io.IOException: 
hdfs://hadoop01.woolford.io:8020/user/Hive/warehouse/my_dataframe/part-r-00001.parquet
not a SequenceFile

Wie speichere ich die Tabelle, damit sie in Hive sofort lesbar ist?

9
Alex Woolford

Ich war dort...
Die API ist in dieser Hinsicht irreführend.
DataFrame.saveAsTable erstellt nicht eine Hive-Tabelle, sondern eine interne Spark-Tabellenquelle.
Es speichert auch etwas im Hive-Metastore, aber nicht das, was Sie vorhaben.
Diese Bemerkung wurde von Spark-User-Mailingliste bezüglich Spark 1.3 gemacht. 

Wenn Sie aus Spark eine Hive-Tabelle erstellen möchten, können Sie diesen Ansatz verwenden:
1. Verwenden Sie Create Table ... über SparkSQL für den Hive-Metastore.
2. Verwenden Sie DataFrame.insertInto(tableName, overwriteMode) für die tatsächlichen Daten (Spark 1.3) 

16
Leet-Falcon

Ich habe letzte Woche diese Ausgabe gefunden und konnte einen Workaround finden

Hier ist die Geschichte: Ich kann die Tabelle in Hive sehen, wenn ich die Tabelle ohne partitionBy erstellt habe:

spark-Shell>someDF.write.mode(SaveMode.Overwrite)
                  .format("parquet")
                  .saveAsTable("TBL_Hive_IS_HAPPY")

Hive> desc TBL_Hive_IS_HAPPY;
      OK
      user_id                   string                                      
      email                     string                                      
      ts                        string                                      

Hive kann das Tabellenschema jedoch nicht verstehen (Schema ist leer ...), wenn ich Folgendes mache:

spark-Shell>someDF.write.mode(SaveMode.Overwrite)
                  .format("parquet")
                  .saveAsTable("TBL_Hive_IS_NOT_HAPPY")

Hive> desc TBL_Hive_IS_NOT_HAPPY;
      # col_name                data_type               from_deserializer  

[Lösung]:

spark-Shell>sqlContext.sql("SET spark.sql.Hive.convertMetastoreParquet=false")
spark-Shell>df.write
              .partitionBy("ts")
              .mode(SaveMode.Overwrite)
              .saveAsTable("Happy_Hive")//Suppose this table is saved at /apps/Hive/warehouse/Happy_Hive


Hive> DROP TABLE IF EXISTS Happy_Hive;
Hive> CREATE EXTERNAL TABLE Happy_Hive (user_id string,email string,ts string)
                                       PARTITIONED BY(day STRING)
                                       STORED AS PARQUET
                                       LOCATION '/apps/Hive/warehouse/Happy_Hive';
Hive> MSCK REPAIR TABLE Happy_Hive;

Das Problem ist, dass die mit der Dataframe-API (partitionBy + saveAsTable) erstellte Datenquellentabelle nicht mit Hive kompatibel ist (siehe link ). Wenn Sie spark.sql.Hive.convertMetastoreParquet auf false setzen (wie in doc vorgeschlagen), speichert Spark nur Daten in HDFS, erstellt jedoch keine Tabelle in Hive. Anschließend können Sie manuell in Hive Shell eine externe Tabelle erstellen, deren Schema und Partitionsdefinition auf den Speicherort der Daten zeigt. Ich habe dies in Spark 1.6.1 getestet und es hat für mich funktioniert. Ich hoffe das hilft!

3
Yuan Zhao

enter image description here

enter image description here

metadaten existieren noch nicht. Mit anderen Worten, es werden alle Partitionen, die auf HDFS existieren, jedoch nicht im Metastore, zum Hive-Metastore hinzugefügt.

0
Tutu Kumari

Ich habe es in Pyspark, Spark Version 2.3.0 getan:

erstellen Sie eine leere Tabelle, in der wir Daten speichern oder überschreiben müssen, z.

create table databaseName.NewTableName like databaseName.OldTableName;

dann unter dem Befehl ausführen:

df1.write.mode("overwrite").partitionBy("year","month","day").format("parquet").saveAsTable("databaseName.NewTableName");

Das Problem ist, dass Sie diese Tabelle mit Hive nicht lesen können, aber Sie können mit Spark lesen.

0
dinesh rajput