2017-03-01 56 views
0

我在Stackoverflow上找到類似的帖子。但是,我無法解決我的問題所以,這就是我寫這篇文章的原因。sparks scala typesafe config安全迭代特定列名的值

目的

目的是在加載SQL表(I使用SQL Server),以執行列投影[投影=過濾柱]。

根據斯卡拉食譜這是過濾colums的方式[使用數組]:

sqlContext.read.jdbc(url,"person",Array("gender='M'"),prop) 

不過,我不想硬編碼陣列(所有「col1」,「col2上」,... )在我的Scala代碼中,這就是爲什麼我使用帶有類型安全的配置文件(參見下文)。

配置文件

dataset { 
    type = sql 
    sql{ 
     url = "jdbc://host:port:user:name:password" 
     tablename = "ClientShampooBusinesLimited" 
     driver = "driver" 
     other = "i have a lot of other single string elements in the config file..." 
     columnList = [ 
     { 
      colname = "id" 
      colAlias = "identifient" 
     } 
     { 
      colname = "name" 
      colAlias = "nom client" 
     } 
     { 
      colname = "age" 
      colAlias = "âge client" 
     } 
     ] 
    } 
} 

讓我們專注於 'columnList':在SQL列的名稱exatecly對應於 'colname的'。 'colAlias'是我稍後會用到的一個字段。

​​

configFromFile是由自己在其他自定義類創建data.scala文件。但這並不重要。 columnList的類型是「ConfigList」,這個類型來自類型安全。

主文件

def loadDataSQL(): DataFrame = { 

val url = datasetConfig.dbUrl 
val dbTablename = datasetConfig.DbTableName 
val dbDriver = datasetConfig.DriverName 
val columns = // I need help to solve this 


/* EDIT 2 march 2017 
    This code should not be used. Have a look at the accepted answer. 
*/ 
sparkSession.read.format("jdbc").options(
    Map("url" -> url, 
    "dbtable" -> dbTablename, 
    "predicates" -> columns, 
    "driver" -> dbDriver)) 
    .load() 
} 

所以我所有的問題是爲了把它們放在一個合適的陣列來提取「colnames的價值觀。有人可以幫我寫出'val列'的正確的操作符嗎?

感謝

回答

1

如果你正在尋找一種方式來讀取colname值列表爲斯卡拉陣列 - 我覺得這個做的:

import scala.collection.JavaConverters._ 

val columnList = configFromFile.getConfigList("dataset.sql.columnList") 
val colNames: Array[String] = columnList.asScala.map(_.getString("colname")).toArray 

使用隨機提供的文件,這將導致Array(id, name, age)

編輯: 至於你的實際目標,我居然不知道叫predication任何選項(我也不能使用Spark 2.0.2在源代碼中找到證據)。

JDBC數據源根據所用查詢中選擇的實際列執行「投影下推」。換句話說 - 只有選擇列會從數據庫中讀取,這樣你就可以在select使用colNames陣列立即DF創建以下,如:

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

sparkSession.read 
    .format("jdbc") 
    .options(Map("url" -> url, "dbtable" -> dbTablename, "driver" -> dbDriver)) 
    .load() 
    .select(colNames.map(col): _*) // selecting only desired columns 
+0

親愛Tzach瑣,這是exactely我一直在尋找對於。非常感謝你的幫助。 – S12000

+0

但是,在「預測」 - >列中出現錯誤,它表示「過載」方法。你知道什麼是問題嗎?謝謝 – S12000

+0

不確定你所指的錯誤,但我更新了我的答案,希望能幫助你實際讀取DB –