2016-12-27 16 views
2

データベースからデータを読み込むことができますが、このデータを処理します。 問題はいくつかのテーブルに 'String'という日付の列がありますが、他のものは 'timestamp'として扱います。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) 
関連する問題