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.
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")
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.