【问题标题】:How to keep partition columns when reading in ORC files in Spark在 Spark 中读取 ORC 文件时如何保留分区列
【发布时间】:2019-02-17 13:15:30
【问题描述】:

在 Spark 中读取 ORC 文件时,如果在路径中指定分区列,则该列将不会包含在数据集中。例如,如果我们有

val dfWithColumn = spark.read.orc("/some/path") 

val dfWithoutColumn = spark.read.orc("/some/path/region_partition=1")

那么 dfWithColumn 将有一个 region_partition 列,但 dfWithoutColumn 不会。如何指定我想要包含所有列,即使它们已分区?

我在 scala 上使用 spark 2.2。

编辑:这是一个可重复使用的 Spark 程序,它将从命令行接收其参数;即使用户传入表的特定分区而不是整个表,我也希望程序能够工作。因此,使用 Dataset.filter 不是一种选择。

【问题讨论】:

  • 如果第二行的目的是只获取该分区的数据,为什么不使用列信息过滤DF?由于 DF 是惰性求值的,谓词会被下推,并且没有读取整个文件的开销
  • 我对问题的解释与 tgecanswers 不同

标签: apache-spark apache-spark-sql orc


【解决方案1】:

不要在路径中添加分区列,而是将它们添加为过滤器。将您的代码修改为 -

val dfWithColumn = spark.read.orc("/some/path/").where($"region_partition" === 1)

这将正确识别架构并仅读取“region_partition=1”目录的数据。

【讨论】:

  • 查看我的编辑;我不想只读取某个分区,我希望即使用户传入某个分区而不是整个表,我的程序也能正常工作。
【解决方案2】:

如果目标是加载一个分区而不是整个数据,那么您可以从 spark 的延迟加载中受益并执行以下操作:

val dfWithColumn = spark.read.orc("/some/path") 
dfWithColumn= dfWithColumn.where($"region_partition" === 1)

通过这样做,您将从文件夹中获取数据:

"/some/path/region_partition=1"

这样做的好处是您保留了原始结构,并在数据集中包含分区列。

但是,如果您打算操纵读取的数据集以添加具有某些值的列,我建议使用以下方法:

与列

【讨论】:

  • 查看我的编辑;我不想只读取某个分区,我希望即使用户传入某个分区而不是整个表,我的程序也能正常工作。
【解决方案3】:

和镶木地板一样。

参考:https://spark.apache.org/docs/latest/sql-data-sources-parquet.html#partition-discovery

df = spark.read.option("basePath", "file://foo/bar/")
         .orc("file://foo/bar/partition_column=XXX")

df 有一个“partition_column”列。

【讨论】:

    猜你喜欢
    • 2017-08-07
    • 1970-01-01
    • 1970-01-01
    • 2015-08-27
    • 2015-12-04
    • 2018-10-04
    • 1970-01-01
    • 2018-01-31
    • 1970-01-01
    相关资源
    最近更新 更多