2016-08-22 28 views
0

當讀取是BigInt類型的MySQL的列(例如BIGINT(21) UNSIGNED下文),火花不能在下面的代碼段投java.math.BigDecimalString火花1.4.1:問題時讀取的MySQL BIGINT列

val driver = "com.mysql.jdbc.Driver" 
val server = ... 
val infoSchema = "INFORMATION_SCHEMA" 
val port = 3306 
val user = ... 
val pw = ... 
val dbUrl = s"jdbc:mysql://$server:$port/$infoSchema" 

val dbProperties = new java.util.Properties() 
dbProperties.setProperty("driver", driver) 
dbProperties.setProperty("user", user) 
dbProperties.setProperty("password", pw) 

val schema = ... 
val table = ... 

val cols = sqlContext.read.jdbc(dbUrl, "COLUMNS", dbProperties) 
    .filter(col("TABLE_SCHEMA") === schema && col("TABLE_NAME") === table) 
    .map(_.getValuesMap[String](Seq("ORDINAL_POSITION", "COLUMN_NAME"))) 
    .collect() 
    .toList 

cols.map(e => e("COLUMN_NAME")) 
cols.map(e => e("ORDINAL_POSITION")) // java.math.BigDecimal cannot be cast to java.lang.String 

然而,當我做以下事情時,沒有問題:

val num = new java.math.BigDecimal(1) 
num.toString 

這是一個錯誤還是我錯過了什麼?

回答

1

Row.getValuesMap[T]不用於類型鑄造。相反,它明確指出,值爲T(內部僅爲get,後跟asInstanceOf[T]),而BigDecimal顯然不是String

您可以:

  • 添加隱式轉換。使用_.getValuesMap[Any]
  • 在映射之前使用SQL強制轉換。

    withColumn("ORDINAL_POSITION", $"ORDINAL_POSITION".cast(StringType)) 
    

但說實話,說實話這些選項是比較難看的,更有意義,直接提取值:

sqlContext.read.jdbc(...).filter(...) 
    .select("ORDINAL_POSITION", "COLUMN_NAME") 
    .rdd 
    .map { case Row(i: java.math.BigDecimal, c: String) => (i, c) }