Spark cast column to sql type存储在string中

时间:2017-08-31 12:28:03

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

简单的请求是我需要帮助向数据帧添加列,但是,列必须为空,其类型来自... spark.sql.types,并且必须从字符串定义类型。

我可以用ifs或case做到这一点,但我正在寻找更优雅的东西。不需要为org.apache.spark.sql.types中的每个类型编写案例的东西

如果我这样做:

df = df.withColumn("col_name", lit(null).cast(org.apache.spark.sql.types.StringType))

它按预期工作,但我将类型存储为字符串,

var the_type = "StringType"

或     var the_type =" org.apache.spark.sql.types.StringType"

我无法通过从字符串中定义类型来使其工作。

对于那些感兴趣的人更多细节:我有一个包含元组(col_name,col_type)的集合作为字符串,我需要为2个数据帧之间的未来联合添加具有正确类型的列。

我目前有这个:

for (i <- set_of_col_type_tuples) yield {
    val tip = Class.forName("org.apache.spark.sql.types."+i._2)
    df = df.withColumn(i._1, lit(null).cast(the_type))
    df }

如果我使用

val the_type = Class.forName("org.apache.spark.sql.types."+i._2)

我得到了

error: overloaded method value cast with alternatives:   (to: String)org.apache.spark.sql.Column <and>   (to: org.apache.spark.sql.types.DataType)org.apache.spark.sql.Column  cannot be applied to (Class[?0])

如果我使用

val the_type = Class.forName("org.apache.spark.sql.types."+i._2).getName()

这是一个字符串,所以我得到了:

org.apache.spark.sql.catalyst.parser.ParseException: mismatched input '.' expecting {<EOF>, '('}(line 1, pos 3)
== SQL == org.apache.spark.sql.types.StringType
---^^^

编辑:所以,为了清楚起见,该集合包含这样的元组(&#34; col1&#34;,&#34; IntegerType&#34;),(&#34; col2&#34;,&# 34; StringType&#34;)not(&#34; col1&#34;,&#34; int&#34;),(&#34; col2&#34;,&#34; string&#34;)。简单演员(i._2)不起作用。

谢谢。

1 个答案:

答案 0 :(得分:4)

您可以使用重载方法cast,它有一个String作为参数:

val stringType : String = ...
column.cast(stringType)
  

def cast(to:String):Column

     

使用规范字符串将列转换为其他数据类型   表示类型。

您还可以扫描所有数据类型:

val types = classOf[DataTypes]
    .getDeclaredFields()
    .filter(f => java.lang.reflect.Modifier.isStatic(f.getModifiers()))
    .map(f => f.get(new DataTypes()).asInstanceOf[DataType])

现在types是Array [DataType]。您可以将其翻译为地图:

val typeMap = types.map(t => (t.getClass.getSimpleName.replace("$", ""), t)).toMap

并在代码中使用:

column.cast(typeMap(yourType))