如何让pyspark显示整个查询计划而不是......如果有很多字段?

col*_*ang 9 apache-spark pyspark

星火 v2.4

spark = SparkSession \
    .builder \
    .master('local[15]') \
    .appName('Notebook') \
    .config('spark.sql.debug.maxToStringFields', 2000) \
    .config('spark.sql.maxPlanStringLength', 2000) \
    .config('spark.debug.maxToStringFields', 2000) \
    .getOrCreate()

df = spark.createDataFrame(spark.range(1000).rdd.map(lambda x: range(100)))
df.repartition(1).write.mode('overwrite').parquet('test.parquet')

df = spark.read.parquet('test.parquet')
df.select('*').explain()

== Physical Plan ==

 ReadSchema: struct<_1:bigint,_2:bigint,_3:bigint,_4:bigint,_5:bigint,_6:bigint,_7:bigint,_8:bigint,_9:bigint,...
Run Code Online (Sandbox Code Playgroud)

注意:spark.debug.maxToStringFields通过扩展FileScan parquet [_1#302L,_2#303L,... 76 more fields],而不是架构部分有所帮助。

注2:我不仅对ReadSchema,而且PartitionFiltersPushedFilters... 都被截断了。

更新

Spark 3.0 引入了explain('formatted')它以不同的方式布局信息并且不应用截断。

col*_*ang 8

Spark 3.0 引入了explain('formatted')以不同方式布局信息并且不应用截断的功能。


col*_*ang 5

恐怕没有简单的方法

https://github.com/apache/spark/blob/v2.4.2/sql/core/src/main/scala/org/apache/spark/sql/execution/DataSourceScanExec.scala#L57

它被硬编码为不超过 100 个字符

  override def simpleString: String = {
    val metadataEntries = metadata.toSeq.sorted.map {
      case (key, value) =>
        key + ": " + StringUtils.abbreviate(redact(value), 100)
    }
Run Code Online (Sandbox Code Playgroud)

最后我一直在使用

def full_file_meta(f: FileSourceScanExec) = {
    val metadataEntries = f.metadata.toSeq.sorted.flatMap {
      case (key, value) if Set(
          "Location", "PartitionCount",
          "PartitionFilters", "PushedFilters"
      ).contains(key) =>
        Some(key + ": " + value.toString)
      case other => None
    }

    val metadataStr = metadataEntries.mkString("[\n  ", ",\n  ", "\n]")
    s"${f.nodeNamePrefix}${f.nodeName}$metadataStr"

}

val ep = data.queryExecution.executedPlan

print(ep.flatMap {
    case f: FileSourceScanExec => full_file_meta(f)::Nil
    case other => Nil
}.mkString(",\n"))
Run Code Online (Sandbox Code Playgroud)

这是一个黑客,总比没有好。