为什么即使指定了所有值,Spark SQL也会为字符串列变为可为空?

时间:2017-03-31 19:11:32

标签: apache-spark apache-spark-sql apache-spark-dataset

所以对于这样的事情:

case class RandomClass(stringOne: String, stringTwo: String, numericOne: Int)
val ds = Seq(
  RandomClass("a", null, 1),  
  RandomClass("a", "x", 3), 
  RandomClass("a", "y", 4), 
  RandomClass("a", null, 5)
).toDS()

ds.printSchema()

结果

root
 |-- stringOne: string (nullable = true)
 |-- stringTwo: string (nullable = true)
 |-- numericOne: integer (nullable = false)

为什么stringOnenullable?奇怪,numericOne被正确推断。我想我只是缺少一些关于Dataset和DataFrame API之间的关系的东西吗?

2 个答案:

答案 0 :(得分:2)

  

为什么String可以为空?

因为Scala Int只是一个Java字符串而不像Scala null可以是null。实际内容(存在{{1}}值或缺少值)根本无关紧要。

另见spark why do columns change to nullable true

答案 1 :(得分:1)

根据推断类型是否位于Scala对象层次结构的AnyRefAnyVal侧,Spark确实可以对可空性进行最佳猜测,但请注意,它可能更复杂比起那个来说。例如,在处理Parquet文件时,出于兼容性目的,所有被推断为nullable

同时,当您创建架构时,如果您愿意,可以随处设置nullable = true

StructField(fieldName, LongType, nullable = true)

// or using a "DSL"
$"fieldName".long.copy(nullable = false)