我正在尝试通过一个新项目设置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文件来进行测试和本地开发案例
答案 0 :(得分:2)
您可以使用案例类从编码器中提取模式,然后在阅读时将其传递
val schema = implicitly[Encoder[Test]].schema
spark.read.schema(schema).json("testpath")