2016-11-23 23 views
3

我正在將我的spark應用程序連接到DashDB。目前,我可以加載我的數據就好了。將JDBC驅動到帶有CLOB錯誤的DashDB(DB2)

但是,我無法將DataFrame保存到DashDB。

任何見解都會有所幫助。

var jdbcSets = sqlContext.read.format("jdbc").options(Map("url" -> url, "driver" -> driver, "dbtable" -> "setsrankval")).load() 
    jdbcSets.registerTempTable("setsOpponentRanked") 
    jdbcSets = jdbcSets.coalesce(10) 
    sqlContext.cacheTable("setsOpponentRanked") 

然而,當我試圖挽救大DataFrames,我得到的錯誤:

DB2 SQL錯誤:SQLCODE = -1666,SQLSTATE = 42613,則sqlerrmc = CLOB,DRIVER = 26年4月19日

的代碼我使用保存數據如下:

val writeproperties = new Properties() 
    writeproperties.setProperty("user", "dashXXXX") 
    writeproperties.setProperty("password", "XXXXXX") 
    writeproperties.setProperty("rowId", "false") 
    writeproperties.setProperty("driver", "com.ibm.db2.jcc.DB2Driver") 
    results.write.mode(SaveMode.Overwrite).jdbc(writeurl, "players_stat_temp", writeproperties) 

示例測試數據集在這裏可以看到:

println("Test set: "+results.first()) 
Test set: ['Damir DZUMHUR','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test','test',null,null,null,null,null,null,null] 

數據幀架構如下:

root 
|-- PLAYER: string (nullable = true) 
|-- set01: string (nullable = true) 
|-- set02: string (nullable = true) 
|-- set12: string (nullable = true) 
|-- set01weakseed: string (nullable = true) 
|-- set01medseed: string (nullable = true) 
|-- set01strongseed: string (nullable = true) 
|-- set02weakseed: string (nullable = true) 
|-- set02medseed: string (nullable = true) 
|-- set02strongseed: string (nullable = true) 
|-- set12weakseed: string (nullable = true) 
|-- set12medseed: string (nullable = true) 
|-- set12strongseed: string (nullable = true) 
|-- set01weakrank: string (nullable = true) 
|-- set01medrank: string (nullable = true) 
|-- set01strongrank: string (nullable = true) 
|-- set02weakrank: string (nullable = true) 
|-- set02medrank: string (nullable = true) 
|-- set02strongrank: string (nullable = true) 
|-- set12weakrank: string (nullable = true) 
|-- set12medrank: string (nullable = true) 
|-- set12strongrank: string (nullable = true) 
|-- minibreak: string (nullable = true) 
|-- minibreakweakseed: string (nullable = true) 
|-- minibreakmedseed: string (nullable = true) 
|-- minibreakstrongseed: string (nullable = true) 
|-- minibreakweakrank: string (nullable = true) 
|-- minibreakmedrank: string (nullable = true) 
|-- minibreakstrongrank: string (nullable = true) 

我已經看過了JDBC DB2Dialect和看到,StringType代碼被映射到CLOB。我想知道以下內容是否有幫助:

private object DB2CustomDialect extends JdbcDialect { 
    override def canHandle(url: String): Boolean = url.startsWith("jdbc:db2") 
    override def getJDBCType(dt: DataType): Option[JdbcType] = dt match { 
      case StringType => Option(JdbcType("VARCHAR(10000)", java.sql.Types.VARCHAR)) 
      case BooleanType => Option(JdbcType("CHAR(1)", java.sql.Types.CHAR)) 
      case _ => None 
    } 
} 

回答

1

是的的確,DB2Dialect的當前實現並不是最優的。我們將看看,並可能會創建一個pull請求,將StringType映射更改爲VARCHAR。

我猜想在第一個地方使用CLOB的原因在於,如果希望能夠存儲所有長度的字符串,而VARCHAR最大限制爲DB2/dDBDB頁面大小,則這樣做更安全。但我認爲人們不太可能會將很長的字符串放入數據框的屬性中,並且CLOB會引起各種操作故障,例如,它在DB2中的COLUMN ORGANIZED表中不受支持,這是dashDB中的默認表類型,這就是爲什麼在嘗試將數據框寫入dashDB時遇到問題。但是CLOB對於DB2中的IO性能也存在問題,因爲它不一定像所有其他表數據一樣緩存在數據庫內存中。

作爲現在的解決方法,您可以做的事情確實只是註冊一個自定義方言,正如您在JdbcDialects.registerDialect()中提出的那樣,直到接受提到的請求爲止。

+0

我有完全相同的問題,但我使用PySpark。我怎樣才能解決這個問題? –

+0

您可以在使用Pixidust的Scala橋接功能的PySpark筆記本中應用此修補程序。我寫了一篇關於整個問題和解決方案的博客文章,其中包含示例筆記本的鏈接:http://datascience.ibm.com/blog/working-with-dashdb-in-data-science-experience/ –

+0

我已經看到了這個文章之前,我實際上使用IBM的spark-submit而不是Notebooks/DSX。你是否說我需要在本地修復我的腳本,然後將它提交到Spark Cluster?由於Spark集羣是託管服務,是否安裝了所有這些依賴項? –

1

通過添加自定義方言很好地工作。

JdbcDialects.registerDialect(new DB2CustomDialect()) 
0

請注意,DSX(即datascience.ibm.com)尚未解決此問題。因此,在使用dashDB的DSX中使用筆記本電腦時,現在不再需要部署自定義方言。

相關問題