2015-09-22 62 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]