PySpark 1.5 & MSSQL jdbc

Posted

技术标签:

【中文标题】PySpark 1.5 & MSSQL jdbc【英文标题】: 【发布时间】:2016-02-26 17:06:27 【问题描述】:

我在 Cloudera YARN 上的 Spark 1.5 上使用 PySpark,在 Centos 6 机器上使用 Python 3.3。 SQL Server 实例是 SQL Server Enterprise 64 位。下面列出了 SQL Server 驱动程序; sqljdbc4.jar;我已经添加到我的 .bashrc

export SPARK_CLASSPATH="/var/lib/spark/sqljdbc4.jar"
export PYSPARK_SUBMIT_ARGS="--conf spark.executor.extraClassPath="/var/lib/spark/sqljdbc4.jar" --driver-class-path="/var/lib/spark/sqljdbc4.jar" --jars="/var/lib/spark/sqljdbc4.jar" --master yarn --deploy-mode client"

当我启动 Spark 时,我可以看到确认

SPARK_CLASSPATH was detected (set to '/var/lib/spark/sqljdbc4.jar')

我有一个看起来像这个架构的数据框

root
 |-- daytetime: timestamp (nullable = true)
 |-- ip: string (nullable = true)
 |-- tech: string (nullable = true)
 |-- th: string (nullable = true)
 |-- car: string (nullable = true)
 |-- min_dayte: timestamp (nullable = true)
 |-- max_dayte: timestamp (nullable = true)

我已经在我的 MS SQL 服务器中创建了一个名为“dbo.shaping”的空表,其中 3 个时间戳列将是 datetime2(7),其他列是 nvarchar(50)。

我尝试使用这个从 PySpark 导出数据帧

properties = "user": "<username>", "password": "<password>" 

df.write.format('jdbc').options(url='<IP>:1433/<dbname>', dbtable='dbo.shaping',driver="com.microsoft.sqlserver.jdbc.SQLServerDriver",properties=properties)

我收到以下回溯错误

Py4JError: An error occurred while calling o250.option. Trace:
py4j.Py4JException: Method option([class java.lang.String, 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(Thread.java:744)

我的方法至少是正确的吗,也许这个错误与写入特定类型的数据有关,即我的数据结构有问题,而不是我的代码?

【问题讨论】:

您正在复活一个已有一年多的问题。您是否已按照要求验证它仍然相关(面对新版本软件等问题)? 无法在此基础设施上进行软件更新。必须是 pyspark 1.5 解决方案。 pyspark 1.5 是一回事,但用于 SQL Server 的 Microsoft JDBC 驱动程序也进行了更新。您的错误具有组件之间版本不匹配的所有特征,只是不太清楚哪些。我建议明确列出您正在使用的所有内容(python、pyspark、JDBC 驱动程序、SQL Server、OS)的版本号,否则几乎没有希望有人复制它。 (这也是为什么我怀疑这是否“广泛适用于大量受众”,但我没有使用 pyspark 的经验。) 【参考方案1】:

您不能将dict 用作options 的值。 options 方法只需要 str 参数(Scala docs 和 PySpark annotations)并扩展为对 Java option 的单独调用。

在当前的 Spark 版本中,值为 automatically converted to string,因此您的代码会静默失败,但 it isn't the case in 1.5。

由于properties 无论如何都是特定于JDBC 驱动程序的,所以您应该使用jdbc 方法:

properties = 
    "user": "<username>", "password": "<password>", "driver": 
    "com.microsoft.sqlserver.jdbc.SQLServerDriver"

df.write.jdbc(
    url='<IP>:1433/<dbname>',
    table='dbo.shaping',
    properties=properties)

虽然解包属性也应该可以工作:

.options(
    url='<IP>:1433/<dbname>',
    dbtable='dbo.shaping',
    driver="com.microsoft.sqlserver.jdbc.SQLServerDriver",
    **properties)

一般来说,当你看到:

py4j.Py4JException: Method ... does not exist

它通常表示本地 Python 类型与所使用的 JVM 方法所期望的类型不匹配。

另见:How to use JDBC source to write and read data in (Py)Spark?

【讨论】:

我包含了“用户”、“密码”和“驱动程序”的属性;就像你在这里一样。但是,我现在收到错误“Py4JJavaError:调用 o230.jdbc 时发生错误。 :java.sql.SQLException:找不到适合'的驱动程序。 ..是否有可能b / c我在YARN上,作为驱动程序并包含在我的Mgmt / Execution节点上的.bashrc中的.jar文件不在每个其他非主节点的同一目录中?因此,当我使用多个节点时,有些没有jar? JDBC 驱动程序必须存在于每个工作节点上。我个人会使用--packages 选项,认为在客户端模式下,您应该能够使用--jars 传递本地jar。

以上是关于PySpark 1.5 & MSSQL jdbc的主要内容,如果未能解决你的问题,请参考以下文章

1.5编程基础之循环控制44:第n小的质数

无法使用 Jupyter 笔记本上的 pyspark 从 Apache Spark 连接到 MS SQL

Mssql 2012 与 PHP & Mysql 到 Mssql 迁移

IntelliJ IDEA 13 使用 Java 1.5,尽管设置为 1.7

PySpark 中的 countApproxDistinctByKey

在 PySpark 中通过 JDBC 实现 SQL Server