2015-09-22 59 views
1

需要编写一个列名列表的方法&列表类型(JDBC)&返回一个将用于创建DataFrame的StructTypeJdbc数据类型为Spark SQL数据类型

我知道我可以用一堆case语句编写一个方法来将JDBC列类型转换为适当的DataType(例如StringType,IntegerType等),但是想知道这种方法是否已经存在。

有一个DataType.fromJson方法,但我不知道/理解我需要传递给它的JSON的结构。

示例输入:用户名,年龄,工资列类型的
列表::

列名的列表java.lang.String中,java.lang.Long中,java.lang.Double中

回答

0

如果您可以使用具有给定架构的表访问JDBC源,您可以简单地从那里复制:

val jdbcOptions: Map[String, String] = ??? 
val jdbcSchema = sqlContext.load("jdbc", jdbcOptions).schema 

JSON表示非常简单。每个StructField被表示为具有字段metadata,name,nullabletype的文档。

{"metadata":{},"name":"f","nullable":true,"type":"string"} 

对于大多数应用程序,你可以忽略metadata并专注于其余三个。棘手的部分是从Java类映射到type,但一个天真的解决方案可以看起来像这样:

import net.liftweb.json.JsonDSL._ 
import net.liftweb.json.{compact, render} 

val columns = Seq(
    ("UserName", "java.lang.String"), 
    ("Age", "java.lang.Long"), 
    ("Salary", "java.lang.Double") 
).map{case (n, t) => (n, t.split("\\.").last.toLowerCase)} 

val fields = columns.map {case (n, t) => (
    ("metadata" -> Map.empty[String, String]) ~ 
    ("name" -> n) ~ 
    ("nullable" -> false) ~ 
    ("type" -> t) 
)} 

val schemaJSON = compact(render(("fields" -> fields) ~ ("type" -> "struct")) 
val schema = DataType.fromJson(schemaJSON).asInstanceOf[StructType]