尝试从UDF

时间:2016-08-12 07:31:30

标签: scala apache-spark dataframe hadoop apache-spark-sql

我正在尝试使用scala在spark框架中编写内联函数,它将获取字符串输入,执行sql语句并返回一个字符串值

val testfunc: (String=>String)= (arg1:String) => 
{val k = sqlContext.sql("""select c_code from r_c_tbl where x_nm = "something" """)                               
 k.head().getString(0)
}

我正在将此scala函数注册为UDF

   val testFunc_test = udf(testFunc)

我在hive表上有一个数据框

    val df = sqlContext.table("some_table")

然后我在withColumn中调用udf并尝试将其保存在新的数据帧中。

    val new_df = df.withColumn("test", testFunc_test($"col1"))

但每当我尝试这样做时,我都会收到错误

16/08/10 21:17:08 WARN TaskSetManager: Lost task 0.0 in stage 1.0 (TID 1,       10.0.1.5): java.lang.NullPointerException
    at org.apache.spark.sql.execution.SQLExecution$.withNewExecutionId(SQLExecution.scala:41)
    at org.apache.spark.sql.DataFrame.withNewExecutionId(DataFrame.scala:2086)
    at org.apache.spark.sql.DataFrame.foreach(DataFrame.scala:1434)

我对火花和斯卡拉相对较新。但我不确定为什么这段代码不能运行。任何见解或工作都将受到高度赞赏。

请注意我没有粘贴整个错误堆栈。如果需要,请告诉我。

1 个答案:

答案 0 :(得分:1)

您不能在UDF中使用sqlContext - UDF必须可序列化才能运送到执行程序,并且上下文(可以被认为是与群集的连接)无法实现被序列化并发送到节点 - 只有驱动程序应用程序(UDF 已定义,但已执行)才能使用sqlContext

看起来你的用例(从表Y中的每个记录执行表X中的选择)最好使用join来完成。