wake-up-neo.com

Spark SQL saveAsTable ist bei Angabe der Partition nicht mit Hive kompatibel

Art des Edge-Falls beim Speichern der Parkett-Tabelle in Spark SQL mit Partition 

#schema definitioin
final StructType schema = DataTypes.createStructType(Arrays.asList(
    DataTypes.createStructField("time", DataTypes.StringType, true),
    DataTypes.createStructField("accountId", DataTypes.StringType, true),
    ...

DataFrame df = hiveContext.read().schema(schema).json(stringJavaRDD);

df.coalesce(1)
    .write()
    .mode(SaveMode.Append)
    .format("parquet")
    .partitionBy("year")
    .saveAsTable("tblclick8partitioned");

Spark warnt:

Bestehende partitionierte Datenquellenbeziehung im Hive-Metastore im Spark SQL-spezifischen Format, das NICHT mit Hive kompatibel ist

Im Bienenstock:

Hive> describe tblclick8partitioned;
OK
col                     array<string>           from deserializer
Time taken: 0.04 seconds, Fetched: 1 row(s)

Offensichtlich ist das Schema nicht korrekt - wenn ich jedoch saveAsTable in Spark SQL ohne Partition verwende, kann die Tabelle problemlos abgefragt werden.

Die Frage ist, wie ich in Spark SQL eine Parketttabelle erstellen kann, die mit Hive mit Partitionsinformationen kompatibel ist.

7
dunlu_98k

Das liegt daran, dass DataFrame.saveAsTable RDD-Partitionen, jedoch keine Hive-Partitionen erstellt. Die Problemumgehung besteht darin, die Tabelle über Hql zu erstellen, bevor DataFrame.saveAsTable aufgerufen wird. Ein Beispiel aus SPARK-14927 sieht folgendermaßen aus:

hc.sql("create external table tmp.partitiontest1(val string) partitioned by (year int)")

Seq(2012 -> "a", 2013 -> "b", 2014 -> "c").toDF("year", "val")
  .write
  .partitionBy("year")
  .mode(SaveMode.Append)
  .saveAsTable("tmp.partitiontest1")
8
rys

Eine Lösung besteht darin, die Tabelle mit Hive zu erstellen und dann die Daten mit ...partitionBy("year").insertInto("default.mytable") zu speichern.

Nach meiner Erfahrung funktionierte das Erstellen der Tabelle in Hive und die Verwendung von ...partitionBy("year").saveAsTable("default.mytable") nicht. Dies ist mit Spark 1.6.2.

1
foghorn