1. 程式人生 > >關於在使用sparksql寫程序是報錯以及解決方案:org.apache.spark.sql.AnalysisException: Duplicate column(s): "name" found, cannot save to file.

關於在使用sparksql寫程序是報錯以及解決方案:org.apache.spark.sql.AnalysisException: Duplicate column(s): "name" found, cannot save to file.

文件加載 mod 但是 路徑 win 錯誤 寫入 技術分享 over

說明:

  spark --version : 2.2.0

  我有兩個json文件,分別是emp和dept:

emp內容如下:

{"name": "zhangsan", "age": 26, "depId": 1, "gender": "male", "salary": 20000}
{"name": "lisi", "age": 36, "depId": 2, "gender": "female", "salary": 8500}
{"name": "wangwu", "age": 23, "depId": 1, "gender": "male", "salary": 5000}
{"name": "zhaoliu", "age": 25, "depId": 3, "gender": "male", "salary": 7000}
{
"name": "marry", "age": 19, "depId": 2, "gender": "female", "salary": 6600} {"name": "Tom", "age": 36, "depId": 1, "gender": "female", "salary": 5000} {"name": "kitty", "age": 43, "depId": 2, "gender": "female", "salary": 6000} {"name": "Tony","age": 36,"depId": 4,"gender":"female","salary": 4030}

dept內容如下:

{"id": 1, "name": "Tech Department"}
{
"id": 2, "name": "Fina Department"} {"id": 3, "name": "HR Department"}

現在我需要通過sparksql將兩個文件加載進來並做join,最後將結果保存到本地

下面是操作步驟:

  1、初始化配置  

 val conf = new SparkConf().setMaster("local[2]").setAppName("Load_Data")
 val sc = new SparkContext(conf)
 val ssc = new sql.SparkSession.Builder()
    .appName("Load_Data_01")
    .master("local[2]")
    .getOrCreate()
 sc
.setLogLevel("error") //測試環境為了少打印點日誌,我將日誌級別設置為error

  2、將兩個json文件加載進來

val df_emp = ssc.read.json("file:///E:\\javaBD\\BD\\json_file\\employee.json")
val df_dept = ssc.read.format("json").load("file:///E:\\javaBD\\BD\\json_file\\department.json")

  3、分別將加載進來的兩個json文件打印出來,看看是否成功載入

df_emp.show()
df_dept.show()

  技術分享圖片

  技術分享圖片

  4、數據加載都沒有問題,接下來二者進行join操作:

df_emp.join(df_dept,df_emp("depId") === df_dept("id"),"left").show()

  技術分享圖片

  5、這樣結果也可以正常打印出來了,貌似是沒有什麽問題了,接下來直接就save就可以了唄,但是進行save的時候就報錯了:

df_emp.join(df_dept,df_emp("depId") === df_dept("id"),"left").write.mode(SaveMode.Append).csv("file:///E:\\javaBD\\BD\\json_file\\rs")

技術分享圖片

於是開始百度,找到了原因,論壇鏈接,大致的意思就是說,要保存的表中有相同的name字段,這樣是不行的,那麽解決方案就很明顯了,讓兩個那麽字段名稱不相同麽,那就分別給他們其別名唄,接下來開始修改代碼:

  1、初始化配置不變

  2、讀文件不變

  3、跟別獲取到兩個DF(json文件加載加載進來之後就是兩個DF)的列明,並進行分別設置別名 

//分別拿出兩張表的列名
val c_emp = df_emp.columns
val c_dept = df_dept.columns
//分別對兩張表的別名進行設置
val emp = df_emp.select(c_emp.map(n => df_emp(n).as("emp_" + n)): _*)
val dept = df_dept.select(c_dept.map(n => df_dept(n).as("dept_" + n)): _*)

  4、接著在進行保存,程序報錯消失:

emp.join(dept,emp("emp_depId") === dept("dept_id"),"left").write.mode(SaveMode.Append).csv("file:///E:\\javaBD\\BD\\json_file\\rs")

  這裏的這個保存的路徑說名一下:我是保存在windows本地,因為我配置了hadoop的環境變量,所以如果寫本地需要這樣寫,如果去掉"file:///"的話,idea會認為是hdfs的路徑,所有會報錯路徑找不到錯誤,如果要寫入到hdfs的話,最好將地址寫全:hdfs://namenode_ip:9000/file技術分享圖片

程序沒有報錯,然後到指定目錄下查看,文件是否寫入:

技術分享圖片

文件已經成功寫入,over

關於在使用sparksql寫程序是報錯以及解決方案:org.apache.spark.sql.AnalysisException: Duplicate column(s): "name" found, cannot save to file.