使用CLOB错误将JDBC解析为DashDB(DB2)

时间:2016-11-23 18:28:25

标签: scala jdbc apache-spark dashdb

我正在努力将我的spark应用程序连接到DashDB。目前,我可以正常加载我的数据。





但是,我无法将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”)
  




但是,当我尝试保存大型DataFrame时,我收到错误:





DB2 SQL错误:SQLCODE = -1666,SQLSTATE = 42613,SQLERRMC = CLOB,DRIVER = 4.19.26


&# xA;

我用来保存数据的代码如下:




  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(“测试集:”+ results.first())
测试集:['Damir DZUMHUR','测试”,‘测试’,‘测试’,‘测试’,‘测试’,‘测试’,‘测试’,‘测试’,‘测试’,‘测试’,‘测试’,‘测试’,‘测试’ , '测试', '测试', '测试', '测试', '测试', '测试', '测试', '测试',NULL,NULL,NULL,NULL,NULL,NULL,NULL]&#XA ;  




DataFrame架构如下:




  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。我想知道以下内容是否有用:




 私有对象DB2CustomDialect扩展了JdbcDialect {
 override def canHandle(url:String):Boolean = url.startsWith(“jdbc:db2”)
 override def getJDBCType(dt:DataType):Option [JdbcType] = dt match {
 case StringType =>选项(JdbcType(“VARCHAR(10000)”,java.sql.Types.VARCHAR))
 case BooleanType =>选项(JdbcType(“CHAR(1)”,java.sql.Types.CHAR))
 case _ =>无
 }
}
  



3 个答案:

答案 0 :(得分:1)

是的,确实DB2Dialect的当前实现不是最佳的。我们将看一下,可能会创建一个pull请求来将StringType映射更改为VARCHAR。

我想在第一个地方使用CLOB的想法是,当您希望能够存储所有长度的字符串时这更安全,而VARCHAR最多受DB2 / dashDB页面大小的限制。但我认为不太可能将非常长的字符串放入数据帧的属性中,并且CLOB会导致所有类型的操作问题,例如:事实上,DB2中的COLUMN ORGANIZED表不支持它,这是dashDB中的默认表类型,这就是为什么在尝试将数据帧写入dashDB时遇到问题的原因。但是CLOB在DB2中的IO性能也存在问题,因为它不像所有其他表数据一样缓存在数据库内存中。

你现在可以做的解决办法确实只是注册一个自己的自定义方言,如上所述,使用JdbcDialects.registerDialect(),直到接受上述拉取请求为止。

答案 1 :(得分:1)

通过添加自定义方言很有效。

JdbcDialects.registerDialect(new DB2CustomDialect())

答案 2 :(得分:0)

注意,DSX(即datascience.ibm.com)尚未解决此问题。因此,在DSX中使用带有dashDB的笔记本时,现在不再需要部署自定义方言。