【问题标题】:Getting HDFS Location of Hive Table in Spark在 Spark 中获取 Hive 表的 HDFS 位置
【发布时间】:2019-10-31 13:14:44
【问题描述】:

我正在尝试使用此查询从 Spark 中的 Hive 分区表中解析位置:

val dsc_table = spark.sql("DESCRIBE FORMATTED data_db.part_table")

我无法在 Spark 中找到任何查询或任何其他方式来专门从此查询中选择 Location 列。

【问题讨论】:

    标签: scala apache-spark hive apache-spark-sql hiveql


    【解决方案1】:

    dataframe API 中的 df.inputFiles 方法将打印文件路径。 它返回构成此 DataFrame 的文件的尽力而为的快照。

    spark.read.table("DB.TableName").inputFiles
    Array[String]: = Array(hdfs://test/warehouse/tablename)
    

    【讨论】:

      【解决方案2】:

      你可以使用spark的读表工具:

      spark.read.table("myDB.myTable").select(input_file_name).take(1) 将产生如下字符串:

      19/06/18 09:59:55 WARN util.Utils: Truncated the string representation of a plan since it was too large. This behavior can be adjusted by setting 'spark.debug.maxToStringFields' in SparkEnv.conf.
      res1: Array[org.apache.spark.sql.Row] = Array([hdfs://nameservice1/my/path/to/table/store/part-00000-d439163c-9fc4-4768-8b0b-c963f5f7d3d2.snappy.parquet])
      

      我使用take(1) 仅打印一行以在此处显示结果。如果您想要所有位置,您可能不想使用它。 从此结果中,您可以相应地解析字符串,以防您只需要位置部分。

      【讨论】:

      • 这是针对 spark 2.4 版本的吗?
      • 没有。我在2.1 中做到了。但这也适用于2.4。我没有看到任何有关弃用任何已使用方法的相关更新。
      • input_file_name 是什么?
      • @GaurangShah 是一个暴露输入文件名称的函数,类似于 hive 的虚拟 INPUT__FILE__NAME 列。在 spark 的源代码中找到它:github.com/apache/spark/blob/master/sql/catalyst/src/main/scala/…
      【解决方案3】:

      您也可以在desc formatted table 上使用.toDF 方法,然后从数据帧中过滤。

      DataframeAPI:

      scala> :paste
      spark.sql("desc formatted data_db.part_table")
      .toDF //convert to dataframe will have 3 columns col_name,data_type,comment
      .filter('col_name === "Location") //filter on colname
      .collect()(0)(1)
      .toString
      

      Result:

      String = hdfs://nn:8020/location/part_table
      

      (or)

      RDD Api:

      scala> :paste
      spark.sql("desc formatted data_db.part_table")
      .collect()
      .filter(r => r(0).equals("Location")) //filter on r(0) value
      .map(r => r(1)) //get only the location
      .mkString //convert as string
      .split("8020")(1) //change the split based on your namenode port..etc
      

      Result:

      String = /location/part_table
      

      【讨论】:

        【解决方案4】:

        在 Pyspark 中没有找到答案

        table_location = spark.sql("describe formatted DB.TableName").filter((F.col('col_name')=='Location')).select("data_type").toPandas().astype(str)['data_type'].values[0]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-11-02
          • 1970-01-01
          • 1970-01-01
          • 2020-10-20
          相关资源
          最近更新 更多