2015-12-02 102 views
1

我的問題與此類似:Apache Spark SQL issue : java.lang.RuntimeException: [1.517] failure: identifier expected但我無法弄清楚問題出在哪裏。我使用SQLite作爲數據庫後端。連接和簡單的選擇語句正常工作。Apache Spark SQL標識符預期異常

的問題的行:

val df = tableData.selectExpr(tablesMap(t).toSeq:_*).map(r => myMapFunc(r)) 

tablesMap包含表名作爲關鍵字和字符串作爲表達式的陣列。打印後,陣列如下所示:

WrappedArray([My Col A], [ColB] || [Col C] AS ColB) 

表名也包含在方括號中,因爲它包含空格。我得到的例外:

Exception in thread "main" java.lang.RuntimeException: [1.1] failure: identifier expected 

我已經確保不要使用任何Spark Sql關鍵字。在我看來,這個代碼失敗的原因有兩種:1)我以某種方式處理列名中的空格錯誤。 2)我處理串接錯誤。

我正在使用類似CSV的資源文件,其中包含我想在我的表格上進行評估的表達式。除了這個文件,我希望允許用戶在運行時指定附加表和它們各自的列表達式。該文件看起來像這樣:

TableName,`Col A`,`ColB`,CONCAT(`ColB`, ' ', `Col C`) 

Appartently這是行不通的。不過,我想重新使用這個文件,當然修改。我的想法是將列與來自字符串數組的表達式(比如現在)映射到一系列的火花列。 (這對我來說是唯一可以想到的解決方案,因爲我希望避免爲所有這些特性拉入所有的Hive依賴關係。)我將爲我的表達式引入一個小的語法,以將原始列名稱標記爲$和一些關鍵字功能如concatas。但我怎麼能這樣做?我嘗試過這樣的事情,但它甚至遠離編譯。

def columnsMapFunc(expr: String) : Column = { 
    if(expr(0) == '$') 
     return expr.drop(1) 
    else 
     return concat(extractedColumnNames).as(newName) 
} 

回答

3

使用包含空格的名稱一般來說是要求的問題,但與反引號替換方括號中應該解決的問題:

val df = sc.parallelize(Seq((1,"A"), (2, "B"))).toDF("f o o", "b a r") 
df.registerTempTable("foo bar") 

df.selectExpr("`f o o`").show 

// +-----+ 
// |f o o| 
// +-----+ 
// | 1| 
// | 2| 
// +-----+ 

sqlContext.sql("SELECT `b a r` FROM `foo bar`").show 

// +-----+ 
// |b a r| 
// +-----+ 
// | A| 
// | B| 
// +-----+ 

對於你必須使用concat功能串聯:

df.selectExpr("""concat(`f o o`, " ", `b a r`)""").show 

// +----------------------+ 
// |'concat(f o o, ,b a r)| 
// +----------------------+ 
// |     1 A| 
// |     2 B| 
// +----------------------+ 

,但它需要Spark 1.4.0中的HiveContext

在實踐中的

df.toDF("foo", "bar") 
// org.apache.spark.sql.DataFrame = [foo: int, bar: string] 

和使用功能的,而不是表達的字符串加載數據之後,我只想重新命名列(concat功能僅在星火> = 1.5.0可用,1.4和更早版本,您需要一個UDF):

import org.apache.spark.sql.functions.concat 

df.select($"f o o", concat($"f o o", lit(" "), $"b a r")).show 

// +----------------------+ 
// |'concat(f o o, ,b a r)| 
// +----------------------+ 
// |     1 A| 
// |     2 B| 
// +----------------------+ 

還有concat_ws函數,它接受分離器的第一個參數:

df.selectExpr("""concat_ws(" ", `f o o`, `b a r`)""") 
df.select($"f o o", concat_ws(" ", $"f o o", $"b a r")) 
+0

concat_ws完美地工作。謝謝 – flowit