从Azure Databricks连接Azure SQL失败及驱动报错求助
解决Azure Databricks连接Azure SQL的两个报错问题
一、解决TCP/IP连接失败报错
针对第一个报错com.microsoft.sqlserver.jdbc.SQLServerException: The TCP/IP connection to the host ...,即使已允许Azure资源访问,仍需检查以下几点:
验证防火墙规则细节:
除了勾选"允许Azure服务和资源访问此服务器",还要确认:- 如果Databricks部署在虚拟网络中,需确保SQL Server的防火墙规则允许VNet的出站IP或服务端点访问;
- 检查是否有网络安全组(NSG)规则阻止了1433端口的出站流量;
- 确认SQL Server的公共访问是否未被设置为"拒绝"(在SQL Server的"网络设置"中查看)。
修正连接URL参数:
Azure SQL不建议设置trustServerCertificate=true,其证书由受信任CA签发,该参数会绕过证书验证可能导致连接异常,应改为trustServerCertificate=false。确认变量正确性:
检查serverName和DatabaseName变量是否完全匹配Azure SQL服务器名称,重点排查拼写错误。
二、解决"No suitable driver"报错
第二个报错由URL格式错误、参数冲突及驱动配置缺失导致:
修复URL格式问题:
修改后的URL存在两处错误:- 包含无效参数
net;loginTimeout=30;; - 重复配置
loginTimeout=30; - URL中同时传入
user和password,又在Sparkoption中重复设置,导致参数冲突。
- 包含无效参数
指定JDBC驱动类:
需显式指定驱动类,确保Databricks能正确加载SQL Server驱动(Databricks Runtime默认包含该驱动,但显式指定更稳妥)。
正确的连接代码示例
# 配置基础参数 server_name = "<你的SQL服务器名称>" database_name = "<你的数据库名称>" username = "<SQL用户名>" password = "<SQL密码>" table_name = "dbo.TableName" # 构造合规的JDBC URL jdbc_url = f"jdbc:sqlserver://{server_name}.database.windows.net:1433;database={database_name};encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;" # 读取Azure SQL数据 df = spark.read.format("jdbc") \ .option("url", jdbc_url) \ .option("dbtable", table_name) \ .option("user", username) \ .option("password", password) \ .option("driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver") \ # 显式指定驱动 .load() # 验证数据加载结果 display(df)
额外建议(服务主体场景优化)
既然使用服务主体创建Databricks,推荐改用服务主体认证替代用户名密码,更符合Azure安全最佳实践:
- 在Azure AD中为服务主体分配SQL DB的对应权限(如"参与者"或数据读写权限);
- 使用以下连接方式:
# 服务主体认证参数 service_principal_id = "<你的服务主体ID>" service_principal_secret = "<你的服务主体密钥>" tenant_id = "<你的租户ID>" # 构造服务主体认证的JDBC URL jdbc_url = f"jdbc:sqlserver://{server_name}.database.windows.net:1433;database={database_name};encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;authentication=ActiveDirectoryServicePrincipal;clientId={service_principal_id};clientSecret={service_principal_secret};tenantId={tenant_id};" # 读取数据 df = spark.read.format("jdbc") \ .option("url", jdbc_url) \ .option("dbtable", table_name) \ .option("driver", "com.microsoft.sqlserver.jdbc.SQLServerDriver") \ .load()
内容的提问来源于stack exchange,提问作者FalloutATS21
相关产品推荐
相关产品推荐

