Using spark MS SQL connector PySpark causes NoSuchMethodError for BulkCopy

Viewed 101

I'm trying to use the MS SQL connector for Spark to insert high volumes of data from pyspark.

After creating a session:

        SparkSession.builder
            .config('spark.jars.packages', 'org.apache.hadoop:hadoop-azure:3.2.0,org.apache.spark:spark-avro_2.12:3.1.2,com.microsoft.sqlserver:mssql-jdbc:8.4.1.jre8,com.microsoft.azure:spark-mssql-connector_2.12:1.2.0')
            

I get the following error:

ERROR executor.Executor: Exception in task 6.0 in stage 12.0 (TID 233)
java.lang.NoSuchMethodError: 'void com.microsoft.sqlserver.jdbc.SQLServerBulkCopy.writeToServer(com.microsoft.sqlserver.jdbc.ISQLServerBulkData)'
        at com.microsoft.sqlserver.jdbc.spark.BulkCopyUtils$.bulkWrite(BulkCopyUtils.scala:110)
        at com.microsoft.sqlserver.jdbc.spark.BulkCopyUtils$.savePartition(BulkCopyUtils.scala:58)
        at com.microsoft.sqlserver.jdbc.spark.SingleInstanceWriteStrategies$.$anonfun$write$2(BestEffortSingleInstanceStrategy.scala:43)
        at com.microsoft.sqlserver.jdbc.spark.SingleInstanceWriteStrategies$.$anonfun$write$2$adapted(BestEffortSingleInstanceStrategy.scala:42)
        at org.apache.spark.rdd.RDD.$anonfun$foreachPartition$2(RDD.scala:1020)
        at org.apache.spark.rdd.RDD.$anonfun$foreachPartition$2$adapted(RDD.scala:1020)
        at org.apache.spark.SparkContext.$anonfun$runJob$5(SparkContext.scala:2236)
        at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:90)
        at org.apache.spark.scheduler.Task.run(Task.scala:131)
        at org.apache.spark.executor.Executor$TaskRunner.$anonfun$run$3(Executor.scala:497)
        at org.apache.spark.util.Utils$.tryWithSafeFinally(Utils.scala:1439)
        at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:500)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:829)

When trying to write data like this:

        try:
            (
                df.write.format("com.microsoft.sqlserver.jdbc.spark")
                    .mode("append")
                    .option("url", url)
                    .option("dbtable", table_name)
                    .option("user", username)
                    .option("password", password)
                    .option("schemaCheckEnabled", "false")
                    .save()
            )
        except ValueError as error:
            print("Connector write failed", error)

I tried different versions of spark and the sql connector but no luck so far. I also tried using a jar for the mssql-jdbc dependency directly:

SparkSession.builder
   .config('spark.jars', '/mssql-jdbc-8.4.1.jre8.jar')
   .config(...)

It still complains that it can't find the method, however if you inspect the JAR file, the method is defined in the source code.

Any tips on where to look are welcome!

1 Answers

We reproduced the same scenario in our environment and it's correctly working now.

There is an issue in JDBC driver 8.2.2 you can use the older version for the library.

Below is the code sample,

enter image description here

Output:

enter image description here

Data got inserted into table from pyspark.

Reference: NoSuchMethodError for BulkCopy.

Related