Scala 引用Spark数据帧的架构时出现NullPointerException

Scala 引用Spark数据帧的架构时出现NullPointerException,scala,apache-spark,Scala,Apache Spark,我正在研究这个用例,它涉及在一些转换之后将数据流转换为数据帧。为了重现错误,我将代码简化为以下代码片段。另外,我在下面提到了我的环境设置 环境: Spark版本:2.2.0 Java:1.8 执行模式:本地/智能 代码: 这会导致NullPointerException,因为我直接在map()中使用df.schema 我不明白的是,如果我使用以下代码(基本上是在转换之前将模式存储为一个值),它就可以正常工作 修改代码: object Tests { def main(args: Array

我正在研究这个用例,它涉及在一些转换之后将数据流转换为数据帧。为了重现错误,我将代码简化为以下代码片段。另外,我在下面提到了我的环境设置

环境:

  • Spark版本:2.2.0

  • Java:1.8

  • 执行模式:本地/智能

代码:

这会导致NullPointerException,因为我直接在
map()
中使用
df.schema

我不明白的是,如果我使用以下代码(基本上是在转换之前将模式存储为一个值),它就可以正常工作

修改代码:

object Tests {

def main(args: Array[String]): Unit = {
val spark: SparkSession =  ...

import spark.implicits._

    val df = List(
        ("jim", "usa"), 
        ("raj", "india"))
        .toDF("name", "country")
    val sc = df.schema

    df.rdd
      .map(x => x.toSeq)
      .map(x => new GenericRowWithSchema(x.toArray, sc))
      .foreach(println)
  }
}
我想知道为什么会发生这种情况,因为
df.rdd
不是一个动作,而且数据帧的状态还有明显的变化


有什么想法吗

之所以发生这种情况,是因为Apache Spark不允许从执行器访问非本地的
数据集,并且行为是预期的


相反,当您将模式提取到变量时,它只是一个可以安全序列化的本地对象。

之所以会发生这种情况,是因为Apache Spark不允许从执行器访问非本地
数据集,并且需要行为


相反,当您将模式提取到变量时,它只是一个可以安全序列化的本地对象。

您不能在转换内部执行操作。schema是一个动作,而map是一个转换。您可以对转换后的数据执行操作,但不能在转换时执行。您不能在转换内执行操作。schema是一个动作,而map是一个转换。您可以对转换的数据执行操作,而不是在转换时执行操作。
object Tests {

def main(args: Array[String]): Unit = {
val spark: SparkSession =  ...

import spark.implicits._

    val df = List(
        ("jim", "usa"), 
        ("raj", "india"))
        .toDF("name", "country")
    val sc = df.schema

    df.rdd
      .map(x => x.toSeq)
      .map(x => new GenericRowWithSchema(x.toArray, sc))
      .foreach(println)
  }
}