控制 spark-sql 和数据帧中的字段可空性

Posted

技术标签:

【中文标题】控制 spark-sql 和数据帧中的字段可空性【英文标题】:controlling fields nullability in spark-sql and dataframes 【发布时间】:2016-04-20 11:42:23 【问题描述】:

我正在使用 spark-sql 的 DataFrame 来实现通用数据集成组件。 基本思想,用户通过命名字段并使用简单的 sql 片段(可以出现在 select 子句中的片段)映射它们来配置字段,组件添加这些列并将它们分组到结构字段中(使用列 DSL 中的struct)。

稍后的处理会获取其中一些结构字段并将它们分组到一个数组中,此时我遇到了一个问题,即其中一个字段在一个元组中可以为空,而在另一个元组中不能为空。

由于字段被分组在一个结构中,我能够提取结构类型,对其进行修改并使用 Column.cast 方法将其应用回整个元组,我不确定如果这种方法适用于***字段(顺便说一句,SQL 强制转换语法不允许指定字段的可空性)。

我的问题是,有没有更好的方法来实现这一点?类似于 nullable() 函数,可应用于表达式以将其标记为可为空,类似于 cast 的工作方式。

示例代码:

val df = (1 to 8).map(x => (x,x+1)).toDF("x","y")
val df6 = df.select(
      functions.struct( $"x" + 1 as "x1", $"y" + 1 as "y1" ) as "struct1",
      functions.struct( $"x" + 1 as "x1", functions.lit(null).cast( DataTypes.IntegerType ) as "y1" ) as "struct2"
    )
val df7 = df6.select( functions.array($"struct1", $"struct2") as "arr" )

此异常失败:

由于数据类型不匹配,无法解析“array(struct1,struct2)”: 函数数组的输入应该都是相同的类型,但它是 [结构,结构]; org.apache.spark.sql.AnalysisException:无法解析 'array(struct1,struct2)' 由于数据类型不匹配:输入到函数 数组应该都是相同的类型,但它是 [struct, 结构];

修复看起来像这样:

//val df7 = df6.select( functions.array($"struct1", $"struct2") as "arr" )
val df7 = df6.select( functions.array($"struct1"  cast df6.schema("struct2").dataType, $"struct2" ) as "arr" )

【问题讨论】:

【参考方案1】:

您可以使用创建Option[Int]udf 使其更简洁:

val optionInt = udf[Option[Int],Int](i => Option(i))

那么在为struct1 创建y1 时需要使用optionInt($"y" + 1)。其他一切都保持不变(尽管为了简洁而进行了编辑)。

val df6 = df.select(
  struct($"x" + 1 as "x1", optionInt($"y" + 1) as "y1" ) as "struct1",
  struct($"x" + 1 as "x1", lit(null).cast(IntegerType) as "y1" ) as "struct2"
)

然后df6.select(array($"struct1", $"struct2") as "arr" ) 工作正常。

【讨论】:

这可能行得通,但它几乎没有缺陷,首先它需要定义 udf,然后必须为所有使用的类型定义它,另一件事是 Catalyst 不知道发生了什么在 udf 内部,这可能意味着失去一些优化机会。

以上是关于控制 spark-sql 和数据帧中的字段可空性的主要内容,如果未能解决你的问题,请参考以下文章

KotlinKotlin 与 Java 互操作 ① ( 变量可空性 | Kotlin 类型映射 | Kotlin 访问私有属性 | Java 调用 Kotlin 函数 )

我可以更改 Spark 数据框中列的可空性吗?

Firebase,Swift:返回类型上的可空性说明符冲突,“可空”与现有说明符“非空”冲突

Kotlin Spring bean 验证可空性

Kotlin空安全 ① ( Kotlin 的空安全机制 | 变量可空性 | 默认变量不可赋空值 | 声明可空类型变量 )

匹配参数的可空性和返回类型的泛型类型参数