Databricks PySpark读取PostgreSQL表连接失败及SSH隧道报错求助
Databricks PySpark读取PostgreSQL报错解决方案
一、直连报错org.postgresql.util.PSQLException: The connection attempt failed.
成因
- 网络策略限制:Databricks集群出站IP未加入PostgreSQL实例白名单,或两者所属网络环境不通,5432端口被安全组、防火墙拦截
- JDBC驱动缺失:Databricks集群默认未预装PostgreSQL JDBC驱动,导致连接初始化失败
- 配置参数错误:代码中
table=Database.table写法错误,Database为字符串变量不能直接用.拼接表名,需按schema+表名的规则组装路径
解决方案
- 先验证网络连通性:在Databricks集群节点执行
nc -zv {servername} 5432测试端口连通性,若不通则先开通网络策略,将Databricks集群出站IP段加入PostgreSQL访问白名单 - 安装JDBC驱动:在集群库管理界面通过Maven坐标安装PostgreSQL驱动,参考坐标为
org.postgresql:postgresql:42.6.0,也可自行上传对应版本jar包 - 修正表路径配置:将读取代码修改为
df = spark.read.jdbc(url=url, table=f"{schema}.{table}", properties=db_properties)
二、SSH隧道连接报错ValueError: No password or public key available!
成因
- SSHTunnelForwarder初始化时缺少SSH服务认证参数,必须指定SSH跳板机的地址、端口、登录用户名,以及对应密码或私钥路径
- Databricks集群节点未存储SSH私钥文件,或私钥读取权限配置错误
- 原代码中开启隧道后仍使用原PostgreSQL服务地址构造JDBC URL,未走本地隧道端口,配置逻辑错误
解决方案
- 补全SSH认证参数,修正后的完整示例代码如下:
from sshtunnel import SSHTunnelForwarder from pyspark.sql import SparkSession servername = "XXXXXXX" port = 5432 Database = "XXXXX" schema = "XXXXX" table = "XXXX" # 补充SSH跳板机配置 ssh_host = "你的跳板机地址" ssh_port = 22 ssh_username = "你的SSH登录用户名" ssh_password = "你的SSH登录密码" # 用私钥认证的话替换为 ssh_private_key = "/dbfs/path/to/your/private_key" db_properties = { 'username': 'XXXXXX', 'password' : 'XXXXXXX', 'driver': 'org.postgresql.Driver' } with SSHTunnelForwarder( (ssh_host, ssh_port), ssh_username=ssh_username, ssh_password=ssh_password, remote_bind_address=('psqlhost', 5432), local_bind_address=('0.0.0.0', 5432) ) as tunnel: # 改为本地隧道地址构造URL url = f"jdbc:postgresql://localhost:5432/{Database}" df = spark.read.jdbc(url=url, table=f"{schema}.{table}", properties=db_properties)
- 多节点Databricks集群不建议使用SSH隧道方案:隧道仅创建在当前执行代码的Driver节点,Executor节点无法访问Driver本地的隧道端口,优先选择直连开通网络策略的方案。
内容的提问来源于stack exchange,提问作者gm tom
相关产品推荐
相关产品推荐

