在GCP Dataproc集群上使用PySpark不通过SSL连接SQL Server的报错问题及解决咨询
让我们一步步拆解你的问题,先解决次要的代码调用错误,再搞定核心的SQL Server连接故障:
一、先修复traceback调用的低级错误
你在异常处理里写的traceback.print_exc(type(ex), ex, ex.__traceback__)是错误的用法:print_exc()方法不需要手动传入异常参数,它会自动捕获当前栈的异常信息。这个错误直接导致了后续的TypeError: '>=' not supported between instances of 'type' and 'int'。
正确的写法二选一:
# 写法1:直接调用print_exc() traceback.print_exc() # 写法2:如果要手动传入异常,用print_exception而不是print_exc traceback.print_exception(type(ex), ex, ex.__traceback__)
二、核心问题:SQL Server连接失败的原因与修复
1. JDBC URL格式不符合规范
SQL Server JDBC驱动不支持用\\拼接主机名和实例名,正确的命名实例指定方式是用;instanceName=INSTANCE_NAME参数。你的原始URL写法会导致驱动无法正确识别目标实例。
修正后的URL(补充了跳过证书验证的参数,避免SSL相关干扰):
url = 'jdbc:sqlserver://DUMMY1234.DUMMY.COM;databaseName=Dummy_DB;encrypt=false;trustServerCertificate=true;instanceName=DUMMY1234'
2. Spark ClassPath配置被覆盖
你连续两次调用config('spark.driver.extraClassPath', ...),第二次的配置会直接覆盖第一次,导致其中一个JDBC驱动jar包未被加载。此外,在Dataproc的YARN集群模式下,Executor节点也需要加载驱动jar,否则执行分布式读取时会找不到驱动。
修正后的ClassPath配置:
# 合并两个jar路径,Linux下用冒号分隔 jar_path = 'path_to_/mssql-jdbc-9.2.0.jre8.jar:path_to_/spark-mssql-connector-1.0.1.jar' spark = SparkSession.builder.master('yarn'). \ config('spark.app.name', 'read_data_sqlserver'). \ config('spark.driver.extraClassPath', jar_path). \ config('spark.executor.extraClassPath', jar_path). \ getOrCreate()
3. 额外的网络与配置检查
除了代码修正,你还需要确认以下环境配置:
- SQL Server端:打开SQL Server配置管理器,确保
TCP/IP协议已启用;如果是命名实例,确保SQL Server Browser服务处于运行状态;同时检查SQL Server是否允许非加密连接(在"服务器属性"->"连接"中确认未勾选"强制加密连接")。 - Dataproc网络:确认集群所在VPC的防火墙规则允许访问SQL Server的1433端口(默认实例)或1434端口(SQL Browser服务,命名实例需要)。可以在Dataproc节点上用
telnet DUMMY1234.DUMMY.COM 1433测试连通性。
完整修正后的代码
from pyspark.sql import SparkSession import traceback def connect_and_read(spark: SparkSession): # 修正JDBC URL格式,添加必要的非SSL连接参数 url = 'jdbc:sqlserver://DUMMY1234.DUMMY.COM;databaseName=Dummy_DB;encrypt=false;trustServerCertificate=true;instanceName=DUMMY1234' driver = 'com.microsoft.sqlserver.jdbc.SQLServerDriver' try: dataframe = spark.read.format('jdbc').option('url', url). \ option('driver', driver). \ option('user', 'username'). \ option('password', 'password'). \ option('dbtable', 'TABLENAME'). \ load() print(f'Count: {dataframe.count()}') dataframe.take(10) except Exception as ex: # 修正traceback调用 traceback.print_exc() pass if __name__ == '__main__': # 合并驱动jar路径,同时配置driver和executor的ClassPath jar_path = 'path_to_/mssql-jdbc-9.2.0.jre8.jar:path_to_/spark-mssql-connector-1.0.1.jar' spark = SparkSession.builder.master('yarn'). \ config('spark.app.name', 'read_data_sqlserver'). \ config('spark.driver.extraClassPath', jar_path). \ config('spark.executor.extraClassPath', jar_path). \ getOrCreate() connect_and_read(spark)
内容的提问来源于stack exchange,提问作者Metadata
相关产品推荐
相关产品推荐

