You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Databricks JDBC连接含特殊字符密码的转义问题问询

问题:Azure Databricks传递含特殊标点的密码导致JDBC连接失败

通过Azure Data Factory调用Databricks,用widget传递包含大量标点符号的密码,变量传递环节正常,但在通过SQL临时视图写入Azure SQL时,因密码中的特殊字符导致解析失败。

原Python代码:

%python
#Get variables to write to DB
input_sql_conn_string = dbutils.widgets.get("dest_sql_server_url")
input_db_name = dbutils.widgets.get("dest_db_name")
input_dest_username = dbutils.widgets.get("dest_username")
input_dest_password = dbutils.widgets.get("dest_password")
input_dest_table_schema = dbutils.widgets.get("dest_table_schema")
input_dest_table_name = dbutils.widgets.get("dest_table_name")

dest_table_full = input_dest_table_schema + "." + input_dest_table_name

#Configure whole connection string
url = f"jdbc:sqlserver://{input_sql_conn_string}:1433;database={input_db_name};user={input_dest_username};password={input_dest_password}"

#Set conf variables so they are accessible by SQL code
spark.conf.set("var.python_sql_url", url)
spark.conf.set("var.python_dest_table", dest_table_full)
spark.conf.set("var.python_username", input_dest_username)
spark.conf.set("var.python_password", input_dest_password)

原SQL代码:

CREATE TEMPORARY VIEW jdbcTable
USING org.apache.spark.sql.jdbc
OPTIONS (
  url ${var.python_sql_url},
  dbtable ${var.python_dest_table},
  user ${var.python_username},
  password ${var.python_password}
);

INSERT INTO TABLE jdbcTable
SELECT m.eventId, m.locationId, m.occurredOn, m.sequenceNumber, m.eventType
FROM unified.events.location m

解决方法

方法1:拆分JDBC配置项,避免拼接完整URL

直接拼接URL时,密码中的分号、等号等特殊字符会破坏JDBC URL格式,改为单独传递各个配置项,让Spark自行处理拼接逻辑:

修改Python代码:

%python
# 获取变量
input_sql_conn_string = dbutils.widgets.get("dest_sql_server_url")
input_db_name = dbutils.widgets.get("dest_db_name")
input_dest_username = dbutils.widgets.get("dest_username")
input_dest_password = dbutils.widgets.get("dest_password")
input_dest_table_schema = dbutils.widgets.get("dest_table_schema")
input_dest_table_name = dbutils.widgets.get("dest_table_name")

dest_table_full = f"{input_dest_table_schema}.{input_dest_table_name}"

# 设置单个配置项,而非完整URL
spark.conf.set("var.sql_server", input_sql_conn_string)
spark.conf.set("var.db_name", input_db_name)
spark.conf.set("var.dest_username", input_dest_username)
spark.conf.set("var.dest_password", input_dest_password)
spark.conf.set("var.dest_table_full", dest_table_full)

对应的SQL代码:

CREATE TEMPORARY VIEW jdbcTable
USING org.apache.spark.sql.jdbc
OPTIONS (
  url "jdbc:sqlserver://${var.sql_server}:1433;database=${var.db_name}",
  dbtable ${var.dest_table_full},
  user ${var.dest_username},
  password ${var.dest_password}
);

INSERT INTO TABLE jdbcTable
SELECT m.eventId, m.locationId, m.occurredOn, m.sequenceNumber, m.eventType
FROM unified.events.location m

方法2:对密码进行URL编码

使用Python的urllib.parse.quote_plus对密码进行URL编码,转义所有特殊字符,确保拼接后的URL格式合法:

修改Python代码中的URL拼接部分:

%python
import urllib.parse

# 获取变量(其余代码同原逻辑)
input_dest_password = dbutils.widgets.get("dest_password")

# 对密码进行URL编码
encoded_password = urllib.parse.quote_plus(input_dest_password)

# 拼接URL时使用编码后的密码
url = f"jdbc:sqlserver://{input_sql_conn_string}:1433;database={input_db_name};user={input_dest_username};password={encoded_password}"

# 后续设置conf变量代码不变
spark.conf.set("var.python_sql_url", url)
# ...其他配置项设置

SQL代码无需修改,保持原逻辑即可。

方法3:直接用Python写入数据(绕开SQL视图)

跳过SQL临时视图环节,直接在Python中读取数据并写入Azure SQL,避免变量跨语言传递时的解析问题:

%python
import urllib.parse

# 获取变量
input_sql_conn_string = dbutils.widgets.get("dest_sql_server_url")
input_db_name = dbutils.widgets.get("dest_db_name")
input_dest_username = dbutils.widgets.get("dest_username")
input_dest_password = dbutils.widgets.get("dest_password")
input_dest_table_schema = dbutils.widgets.get("dest_table_schema")
input_dest_table_name = dbutils.widgets.get("dest_table_name")

dest_table_full = f"{input_dest_table_schema}.{input_dest_table_name}"

# 编码密码并拼接URL
encoded_password = urllib.parse.quote_plus(input_dest_password)
url = f"jdbc:sqlserver://{input_sql_conn_string}:1433;database={input_db_name};user={input_dest_username};password={encoded_password}"

# 读取数据并写入
df = spark.sql("SELECT m.eventId, m.locationId, m.occurredOn, m.sequenceNumber, m.eventType FROM unified.events.location m")
df.write \
  .format("jdbc") \
  .option("url", url) \
  .option("dbtable", dest_table_full) \
  .option("user", input_dest_username) \
  .option("password", input_dest_password) \
  .mode("append")  # 根据需求选择模式:append/overwrite等
  .save()

内容的提问来源于stack exchange,提问作者blobbles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 17:33:17