2016-12-27 52 views
2

我可以從數據庫加載數據,並且使用這些數據做一些處理。 問題是某些表的日期列爲'String',但其他一些則將其視爲'時間戳'。Spark,Scala - 列類型確定

我不知道什麼類型的日期列,直到加載數據。

> x.getAs[String]("date") // could be error when date column is timestamp type 
> x.getAs[Timestamp]("date") // could be error when date column is string type 

這是我如何從spark加載數據。

spark.read 
       .format("jdbc") 
       .option("url", url) 
       .option("dbtable", table) 
       .option("user", user) 
       .option("password", password) 
       .load() 

有沒有什麼方法可以將它們特徵化?或將其轉換爲字符串總是?

回答

5

你可以在列的型(使用數據幀的模式)模式匹配來決定是否解析字符串轉換爲時間戳或只使用時間戳是 - 並使用unix_timestamp功能做實際轉換:

import org.apache.spark.sql.functions._ 
import org.apache.spark.sql.types.StringType 

// preparing some example data - df1 with String type and df2 with Timestamp type 
val df1 = Seq(("a", "2016-02-01"), ("b", "2016-02-02")).toDF("key", "date") 
val df2 = Seq(
    ("a", new Timestamp(new SimpleDateFormat("yyyy-MM-dd").parse("2016-02-01").getTime)), 
    ("b", new Timestamp(new SimpleDateFormat("yyyy-MM-dd").parse("2016-02-02").getTime)) 
).toDF("key", "date") 

// If column is String, converts it to Timestamp 
def normalizeDate(df: DataFrame): DataFrame = { 
    df.schema("date").dataType match { 
    case StringType => df.withColumn("date", unix_timestamp($"date", "yyyy-MM-dd").cast("timestamp")) 
    case _ => df 
    } 
} 

// after "normalizing", you can assume date has Timestamp type - 
// both would print the same thing: 
normalizeDate(df1).rdd.map(r => r.getAs[Timestamp]("date")).foreach(println) 
normalizeDate(df2).rdd.map(r => r.getAs[Timestamp]("date")).foreach(println)