如何使用spark确定分区键/列

piwo6bdm  于 2021-06-26  发布在  Hive
关注(0)|答案(2)|浏览(345)

假设我使用 partitionBy 要将一些数据保存到磁盘(例如按日期),使我的数据看起来像这样:

/mydata/d=01-01-2018/part-00000
/mydata/d=01-01-2018/part-00001
...
/mydata/d=02-01-2018/part-00000
/mydata/d=02-01-2018/part-00001
...

当我使用配置单元和 DataFrame ,所以

val df = sparkSession.sql(s"select * from $database.$tableName")

我知道:
筛选列上的查询 d 会往下推
如果我尝试按 d (例如。 GROUP BY d )
但是,假设我不知道分区键是什么(一些上游作业写入数据,并且没有约定)。在这种情况下,如何让spark告诉我哪个是分区键 d . 类似地,如果我们有多个分区(例如,按月、按周、按天)。
目前我们最好的代码非常难看:

def getPartitionColumnsForHiveTable(databaseTableName: String)(implicit sparkSession: SparkSession): Set[String] = {
    val cols = sparkSession.
      sql(s"desc $databaseTableName")
      .select("col_name")
      .collect
      .map(_.getAs[String](0))
      .dropWhile(r => !r.matches("# col_name"))
    if (cols.isEmpty) {
      Set()
    } else {
      cols.tail.toSet
    }
  }
o2g1uqev

o2g1uqev1#

您也可以使用sql语句来获取此信息 show create table <tablename> , describe extended <tablename> 或者 show partitions <tablename> . 最后一个给出了要分析的最简单的输出:

val partitionCols = spark.sql("show partitions <tablename>").as[String].first.split('/').map(_.split("=").head)
qlvxas9a

qlvxas9a2#

假设你没有 = 以及 / 在分区列值中,可以执行以下操作:

val df = spark.sql("show partitions database.test_table")

val partitionedCols: Set[String] = try { 
  df.map(_.getAs[String](0)).first.split('/').map(_.split("=")(0)).toSet
} catch {
  case e: AnalysisException => Set.empty[String]
}

你应该得到一个 Array[String] 使用分区的列名。

相关问题