去除分配列我分区的数据帧如下:防止DataFrame.partitionBy()从模式
df.write.partitionBy("type", "category").parquet(config.outpath)
的代码给出了预期的结果(即,通过&类型类别划分的数据)。但是,“类型”和“类别”列将从数据/模式中删除。有没有办法来防止这种行为?
去除分配列我分区的数据帧如下:防止DataFrame.partitionBy()从模式
df.write.partitionBy("type", "category").parquet(config.outpath)
的代码给出了预期的结果(即,通过&类型类别划分的数据)。但是,“类型”和“类别”列将从数据/模式中删除。有没有办法来防止这种行为?
我可以想到一个解决方法,这是相当蹩脚的,但工程。
import spark.implicits._
val duplicated = df.withColumn("_type", $"type").withColumn("_category", $"category")
duplicated.write.partitionBy("_type", "_category").parquet(config.outpath)
我,希望有人会比我有更好的回答或解释回答这个问题(如果OP已经找到了更好的解决方案),但是,因为我有同样的问题。
其实对我来说看起来不蹩脚。似乎是'partitionBy()'行为的最佳方法。 – Michael
一般来说,伊万的答案是一个很好的答案。但...
如果您严格阅读和书写火花,您可以在读取数据时使用basePath选项。
https://spark.apache.org/docs/2.2.0/sql-programming-guide.html#partition-discovery
通过传递路径/到/表要么SparkSession.read.parquet或SparkSession.read.load,火花SQL将自动提取的路径中的划分信息。
例子:
val dataset = spark
.read
.format("parquet")
.option("basePath", hdfsInputBasePath)
.load(hdfsInputPath)
是不是一个问题?所有需要的数据仍然编码在目录结构中,因此不会丢失数据。如果你想要一个每个文件的值,你可以尝试'df.repartition(“type”,“category”)。write(...)'但你不会得到好的结构。 – zero323
@ zero323:是的,我同意没有数据丢失。但是,对于某些使用情况,恢复用于分区的列是不平凡的。例如,如果我想在猪中加载数据,我将如何恢复类型和类别列? – Michael
有段时间没有用过猪。 ParquetLoader不能理解开箱即用的结构吗? – zero323