我正在努力将我的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 _ =>无
 }
}
 代码>


答案 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的笔记本时,现在不再需要部署自定义方言。