PySpark使用JDBC写入Oracle时出现setProperty方法不存在报错
Spark JDBC写入Oracle触发Py4J方法不存在异常排查
问题现象
通过PySpark调用DataFrame的JDBC写入接口向Oracle数据库追加数据时,触发py4j.Py4JException异常,已排除字段类型不匹配问题,无法定位报错根因。
复现代码
self.batchsize = 50000 self.tgt_url = 'jdbc:oracle:thin:@' + self.tgt_hostname + ":" + self.tgt_port + "/" + self.tgt_schema self.tgt_connectionProperties = { "user": self.tgt_username, "password": self.tgt_password, "driver": "oracle.jdbc.driver.OracleDriver", "batchszie": self.batchsize } temp_table = self.TgtDatabase + "." + self.TgtTable self.inmemdf.write.jdbc( self.tgt_url, table=temp_table, mode='append', properties=self.tgt_connectionProperties )
报错堆栈
An error occurred while calling o171.setProperty. Trace: py4j.Py4JException: Method setProperty([class java.lang.String, class java.lang.Integer]) does not exist at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:318) at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:326) at py4j.Gateway.invoke(Gateway.java:274) at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132) at py4j.commands.CallCommand.execute(CallCommand.java:79) at py4j.GatewayConnection.run(GatewayConnection.java:238) at java.lang.Thread.run(Thread.java:748)
已完成的排查动作
- 初始判定异常由字段数据类型不匹配引发,已将DataFrame全量字段强制转换为目标Oracle表对应字段类型,异常未解决
根因分析
Java端java.util.Properties类的setProperty方法仅存在单一种方法签名:setProperty(String key, String value),不支持传入Integer类型的值。当PySpark端把Python字典格式的连接参数转换为Java端Properties对象时,遇到非字符串类型的参数值,就会触发“找不到匹配方法”的Py4J反射异常。
结合代码片段可定位两个具体问题:
- 连接参数字典中的批量大小参数存在拼写错误:将
batchsize误写为batchszie,导致Spark无法识别该配置项 - 传入的批量大小值为整数类型,未做字符串转换,和Java端Properties的方法签名不匹配,直接触发反射报错
修复方案
- 修正批量大小参数的拼写错误
- 将整数值类型的连接参数统一转换为字符串格式
修复后的连接属性配置参考:
self.tgt_connectionProperties = { "user": self.tgt_username, "password": self.tgt_password, "driver": "oracle.jdbc.driver.OracleDriver", # 修正拼写,同时将整数转为字符串适配Java Properties的入参要求 "batchsize": str(self.batchsize) }
调整完成后,Spark会将所有连接参数以字符串形式写入Java端的Properties对象,匹配对应方法签名,异常即可消除。
内容的提问来源于stack exchange,提问作者Rafa
相关产品推荐
相关产品推荐

