java.util.HashMap отсутствует в сеансе PySpark
Я работаю с Apache Spark 1.4.0 на Windows 7 x64 с Java 1.8.0_45 x64 и Python 2.7.10 x86 в IPython 3.2.0
Я пытаюсь написать программу на базе DataFrame в записной книжке IPython, которая выполняет чтение и запись в базу данных SQL Server.
Пока я могу читать данные из базы данных
from pyspark.sql import SQLContext
sqlContext = SQLContext(sc)
df = sqlContext.load(source="jdbc",url="jdbc:sqlserver://serverURL", dbtable="dbName.tableName", driver="com.microsoft.sqlserver.jdbc.SQLServerDriver", user="userName", password="password")
и конвертировать данные в панду и делать с ней все что захочу. (Это было немного сложнее, но это работает после добавления sqljdbc42.jar от Microsoft в spark.driver.extraClassPath в spark-defaults.conf)
Текущая проблема возникает, когда я перезаписываю данные обратно на SQL Server с помощью API DataFrameWriter:
df.write.jdbc("jdbc:sqlserver://serverURL", "dbName.SparkTestTable1", dict(driver="com.microsoft.sqlserver.jdbc.SQLServerDriver", user="userName", password="password"))
---------------------------------------------------------------------------
Py4JError Traceback (most recent call last)
<ipython-input-19-8502a3e85b1e> in <module>()
----> 1 df.write.jdbc("jdbc:sqlserver://jdbc:sqlserver", "dbName.SparkTestTable1", dict(driver="com.microsoft.sqlserver.jdbc.SQLServerDriver", user="userName", password="password"))
C:\Users\User\Downloads\spark-1.4.0-bin-hadoop2.6\python\pyspark\sql\readwriter.pyc in jdbc(self, url, table, mode, properties)
394 for k in properties:
395 jprop.setProperty(k, properties[k])
--> 396 self._jwrite.mode(mode).jdbc(url, table, jprop)
397
398
C:\Python27\lib\site-packages\py4j\java_gateway.pyc in __call__(self, *args)
536 answer = self.gateway_client.send_command(command)
537 return_value = get_return_value(answer, self.gateway_client,
--> 538 self.target_id, self.name)
539
540 for temp_arg in temp_args:
C:\Python27\lib\site-packages\py4j\protocol.pyc in get_return_value(answer, gateway_client, target_id, name)
302 raise Py4JError(
303 'An error occurred while calling {0}{1}{2}. Trace:\n{3}\n'.
--> 304 format(target_id, '.', name, value))
305 else:
306 raise Py4JError(
Py4JError: An error occurred while calling o49.mode. Trace:
py4j.Py4JException: Method mode([class java.util.HashMap]) does not exist
at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:333)
at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:342)
at py4j.Gateway.invoke(Gateway.java:252)
at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:133)
at py4j.commands.CallCommand.execute(CallCommand.java:79)
at py4j.GatewayConnection.run(GatewayConnection.java:207)
at java.lang.Thread.run(Unknown Source)
Кажется, проблема в том, что py4j не может найти Java java.util.HashMap
Класс, когда он идет для преобразования моего словаря connectionProperties в объект JVM. Добавление моего rt.jar (с путем) в spark.driver.extraClassPath не решает проблему. Удаление словаря из команды записи позволяет избежать этой ошибки, но, конечно, запись не удается из-за отсутствия драйвера и аутентификации.
Изменить: o49.mode
часть ошибки меняется от запуска к запуску.
1 ответ
Дэвис Лю в списке рассылки Spark обнаружил проблему. Между API Scala и Python есть небольшая разница, которую я пропустил. Вы должны передать строку режима (например, "перезаписать") как 3-й параметр в Python API, но не Scala API. Изменение утверждения следующим образом решает эту проблему:
df.write.jdbc("jdbc:sqlserver://serverURL", "dbName.SparkTestTable1", "overwrite", dict(driver="com.microsoft.sqlserver.jdbc.SQLServerDriver", user="userName", password="password"))