Type de cas Edge, lors de la sauvegarde d'une table de parquet dans Spark SQL avec 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");
Étincelle avertit:
Persistance de la relation source de données partitionnée dans le métastore Hive au format spécifique Spark SQL, qui n'est PAS compatible avec Hive
Dans la ruche:
Hive> describe tblclick8partitioned;
OK
col array<string> from deserializer
Time taken: 0.04 seconds, Fetched: 1 row(s)
Évidemment, le schéma n'est pas correct. Toutefois, si j'utilise saveAsTable
dans Spark SQL sans partition, la table peut être interrogée sans problème.
La question est comment puis-je rendre une table de parquet dans Spark SQL compatible avec Hive avec informations de partition?
En effet, DataFrame.saveAsTable crée des partitions RDD mais pas des partitions Hive, la solution consiste à créer la table via hql avant d'appeler DataFrame.saveAsTable. Un exemple de SPARK-14927 se présente comme suit:
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")
Une solution consiste à créer la table avec Hive, puis à enregistrer les données avec ...partitionBy("year").insertInto("default.mytable")
.
D'après mon expérience, créer la table dans Hive puis utiliser ...partitionBy("year").saveAsTable("default.mytable")
ne fonctionnait pas. Ceci est avec Spark 1.6.2.