Databricks PySpark写入Synapse SQL报错:输入非有效Base-64字符串
问题描述
在Databricks环境中使用PySpark向Azure Synapse SQL Server写入数据时,无论写入什么内容(哪怕是最简测试数据集),都会抛出以下异常:
SQLServerException: The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters
可稳定复现的代码如下:
# create df df = spark.createDataFrame([('A', 5, 0),('A',6, 0),('B',3, 0)], ['id', 'value', 'currentVersion']) # write df.write \ .mode("overwrite") \ .format("com.databricks.spark.sqldw") \ .option("url", "jdbc:sqlserver://<servername>.sql.azuresynapse.net:1433;database=<db>;encrypt=true;trustServerCertificate=true;hostNameInCertificate=*.sql.azuresynapse.net;loginTimeout=30") \ .option("forwardSparkAzureStorageCredentials", "true") \ .option("enableServicePrincipalAuth", "true") \ .option("truncate", "true") \ .option("dbTable", "dbo.test") \ .option("tempDir", "abfss://<fsname>@<storagename>.dfs.core.windows.net/temp") \ .save()
根因分析
报错的核心原因是写入配置存在互斥项冲突:
forwardSparkAzureStorageCredentials参数的作用是让Synapse SQL连接器直接复用Databricks访问ADLS Gen2存储的内置凭证,用来读取写入过程中存在tempDir下的临时staging文件,这个模式下默认使用SQL账号密码做Synapse实例的登录认证enableServicePrincipalAuth参数的作用是开启Azure服务主体全链路认证,连接器启动时会自动读取对应配置项中的服务主体密钥,按Base64格式解析后生成AAD认证令牌
两个参数同时开启时,连接器的认证逻辑出现混乱:它会进入服务主体认证分支,尝试把透传过来的存储访问密钥当成Base64编码的服务主体密钥解析,因为存储密钥的格式不符合Base64解析规则,就会直接抛出非法Base64字符串的错误。
解决步骤
根据你实际使用的认证场景,二选一删除冲突配置,补全对应缺失参数即可:
- 如果使用「存储凭证透传 + SQL账号登录Synapse」的模式:
- 删除
.option("enableServicePrincipalAuth", "true")配置行 - 在JDBC连接url中补充SQL登录的账号密码参数:追加
;user=<你的Synapse SQL管理员/授权用户名>;password=<对应登录密码>
- 删除
- 如果使用「服务主体AAD认证」的模式:
- 删除
.option("forwardSparkAzureStorageCredentials", "true")配置行 - 补全服务主体认证必需的三个配置项:
aad_tenant_id:Azure账号所属的租户IDspark.dw.client.principal:用于认证的客户端服务主体Application IDspark.dw.client.key:对应服务主体的访问密钥
- 删除
配置调整完成后,先运行最简测试样例验证写入逻辑,确认无报错后再同步正式业务数据即可。
内容的提问来源于stack exchange,提问作者John Stud
相关产品推荐
相关产品推荐

