1. 程式人生 > >Spark SQL將資料寫入Mysql表的一些坑

Spark SQL將資料寫入Mysql表的一些坑

轉自:https://blog.csdn.net/dai451954706/article/details/52840011/ 

最近,在使用Spark SQL分析一些資料,要求將分析之後的結果資料存入到相應的MySQL表中。

    但是將資料處理完了之後,存入Mysql時,報錯了:

    

   程式碼的基本形式為: 

 

 
  1. val r1: Dataset[Row] = data.groupBy(***)...

  2.  
  3. r1.write.jdbc(url,"iptimecount",prop)

    根據圖片中的報錯,搜尋資料,得知是由於Spark SQL 中的Save Mode導致的,Spark SQL的官方文件中對Savemode進行了說明:

    

    預設情況下,使用SaveMode.ErrorIfExists,也就是說,當從Spark中插入到MySQL表中的時候,如果表已經存在,則直接報錯,想想真覺得這預設值有點坑。

 於是修改Savemode,將程式碼改成:

   

r1.write.mode(SaveMode.Append).jdbc(url,"iptimecount",prop)


   再次執行,本以為應該會順利存入到資料庫中了,沒想到還是報錯:

    看到這個錯誤,我有點茫然,不清楚是哪裡的問題。

    後來,在一次測試中,將MySQL中將原來的表格刪除後,再次提交任務,能順利將資料存入到MySQL中,但是,使用desc查看錶的結構,發現在Spark SQL中列型別為String型別的,在MySQL中對應為Text型別,於是我猜測應該是我之前建立的表格中,將列的型別定義為char和varchar導致的。

    於是,我刪除表格,重新建立表格,將char和varchar型別改為Text,再次執行,順利的將資料從Spark SQL中存入到了Mysql.

         另附一些注意事項:

 

資料存入Mysql注意事項

A. 儘量先設定好儲存模式

預設為SaveMode.ErrorIfExists模式,該模式下,如果資料庫中已經存在該表,則會直接報異常,導致資料不能存入資料庫.另外三種模式如下:

SaveMode.Append 如果表已經存在,則追加在該表中;若該表不存在,則會先建立表,再插入資料;

SaveMode.Overwrite 重寫模式,其實質是先將已有的表及其資料全都刪除,再重新建立該表,最後插入新的資料;

SaveMode.Ignore 若表不存在,則建立表,並存入資料;在表存在的情況下,直接跳過資料的儲存,不會報錯。

B. 設定儲存模式的步驟為:

org.apache.spark.sql.SaveMode

......

df.write.mode(SaveMode.Append)

C. 若提前在資料庫中手動建立表,需要注意列名稱和資料型別,

下面的原始碼說明了,需要保證Spark SQL中schema中的field name與Mysql中的列名稱一致!

若提前手動建立Mysql表,需要注意Spark SQL 中Schema中的資料型別與Mysql中的資料型別的對應關係,如下圖所示:

特別注意: Scala中的String型別,在MySQL中對應的是Text型別(經過親自測試所知)

上面是本人在Spark SQL 讀取與寫入Mysql方面的遇到的一些坑,特在此備忘。