Spark无法写入然后读取具有空列的JSON格式的数据

时间:2018-08-27 15:34:32

标签: scala apache-spark

我正在尝试通过一个新项目设置spark,并且我有一些案例类是从我公司其他地方的模式生成的,我想以此为模板来以多种格式(镶木地板和json)进行读/写

我注意到json中的一个字段存在问题,该字段是Option [String]。相应的数据通常为空,但有时不为空。当我使用这些数据的子集进行测试时,很有可能该列中的所有行都为空。 Spark似乎检测到了这一点,并为该数据为null的任何行都省​​略了该列。

在阅读时,只要任何一行都有对应的数据,spark都会选择该模式并将其转换回case类。但是,如果它们都不存在,spark将看到缺少的列并失败。

这里有一些代码演示了这一点。

import org.apache.spark.sql.SparkSession

object TestNulls {
  case class Test(str: Option[String])
  def main(args: Array[String]) {
    val spark: SparkSession = SparkSession
      .builder()
      .getOrCreate()
    import spark.implicits._

    val dataset = Seq(
      Test(None),
      Test(None),
      Test(None)
    ).toDS()

    // Because all rows are null, writes {} for all rows
    dataset.write.json("testpath")

    // Fails because column `test` does not exist, even though it is an option
    spark.read.json("testpath").as[Test].show()
  }
}

是否有一种方法可以告诉Spark在缺少可为空的列时不会失败?如果失败,是否可以使用人类可读的格式显示这种行为? json主要是为了使我们可以编写人类readabale文件来进行测试和本地开发案例

1 个答案:

答案 0 :(得分:2)

您可以使用案例类从编码器中提取模式,然后在阅读时将其传递

val schema = implicitly[Encoder[Test]].schema
spark.read.schema(schema).json("testpath")