如何在Python中使用Service Principal ID连接Azure SQL Server
Python通过Service Principal连接Azure SQL Server分步指引
前置准备
- 提前拿到Service Principal的三个核心参数:客户端ID(Application ID)、客户端密钥值、所属Azure AD租户ID
- 持有目标Azure SQL Server的Azure AD管理员权限,用于给服务主体配置库内权限
- 本地已安装17及以上版本的Microsoft ODBC Driver for SQL Server(低版本不支持服务主体认证模式)
第一步:给服务主体配置数据库访问权限
服务主体默认没有任何数据库访问权限,必须先在目标库内创建对应的数据库用户并赋权:
- 用你原来的连接串方式,或者用Azure AD管理员账号登录到你要连接的目标业务数据库(不要停留在master库)
- 执行如下T-SQL命令完成用户创建和授权:
-- 将[]内的内容替换为你自己的Service Principal在Azure AD里的显示名称 CREATE USER [你的Service Principal显示名称] FROM EXTERNAL PROVIDER; -- 按需分配权限,普通读写场景加下面两个角色即可 ALTER ROLE db_datareader ADD MEMBER [你的Service Principal显示名称]; ALTER ROLE db_datawriter ADD MEMBER [你的Service Principal显示名称]; -- 如果需要执行建表、改表等DDL操作,再额外加下面的角色,非必要不分配过高权限 -- ALTER ROLE db_ddladmin ADD MEMBER [你的Service Principal显示名称];
高频踩坑:千万不要在master库执行上面的建用户SQL,必须切换到实际业务库执行,否则后续连接会报登录失败。
第二步:安装Python依赖
# 核心连接依赖 pip install pyodbc # 如果需要配合pandas做数据读写、或者用ORM框架,再装sqlalchemy和azure-identity pip install sqlalchemy azure-identity
安装完成后可以跑下面的代码确认本地ODBC驱动版本符合要求:
import pyodbc print(pyodbc.drivers()) # 输出里要包含"ODBC Driver 17 for SQL Server"或者"ODBC Driver 18 for SQL Server",如果没有就重新装对应版本的驱动
第三步:Python连接代码
方式1:纯pyodbc直连(轻量场景)
直接在连接串里指定服务主体认证模式即可,不需要额外依赖:
import pyodbc # 替换为你的实际配置 SERVER = "你的Azure SQL服务器名.database.windows.net" DATABASE = "目标业务库名" CLIENT_ID = "Service Principal客户端ID" CLIENT_SECRET = "Service Principal客户端密钥" DRIVER = "{ODBC Driver 18 for SQL Server}" # 如果你装的是17版本就改成对应驱动名 conn_str = ( f"DRIVER={DRIVER};" f"SERVER={SERVER};" f"DATABASE={DATABASE};" f"UID={CLIENT_ID};" f"PWD={CLIENT_SECRET};" f"Authentication=ActiveDirectoryServicePrincipal;" f"Encrypt=yes;" f"TrustServerCertificate=no;" ) # 测试连接 conn = pyodbc.connect(conn_str) cursor = conn.cursor() cursor.execute("SELECT TOP 1 name FROM sys.tables") print("连接成功,库内第一个表名:", cursor.fetchone()[0]) cursor.close() conn.close()
方式2:SqlAlchemy连接(适配pandas等数据工具场景)
这种方式通过Azure Identity拿令牌认证,后续要切换系统托管身份、用户认证的时候只需要改Credential部分,代码改动更小:
from sqlalchemy import create_engine from azure.identity import ClientSecretCredential import pandas as pd SERVER = "你的Azure SQL服务器名.database.windows.net" DATABASE = "目标业务库名" TENANT_ID = "Azure AD租户ID" CLIENT_ID = "Service Principal客户端ID" CLIENT_SECRET = "Service Principal客户端密钥" # 生成认证凭据 credential = ClientSecretCredential( tenant_id=TENANT_ID, client_id=CLIENT_ID, client_secret=CLIENT_SECRET ) # 构造连接引擎 engine = create_engine( f"mssql+pyodbc://{SERVER}/{DATABASE}?driver=ODBC+Driver+18+for+SQL+Server&Encrypt=yes&TrustServerCertificate=no", connect_args={ "attrs_before": { 1256: credential.get_token("https://database.windows.net/.default").token.encode("UTF-16-LE") } } ) # 测试查询 df = pd.read_sql("SELECT TOP 10 * FROM 你的测试表", engine) print("查询结果:") print(df)
常见问题排查
- 报错
Login failed for user '<token-identified principal>':优先检查是不是在错的库里建了用户、服务主体名称拼写是否正确、有没有给对应角色权限 - 报不支持
ActiveDirectoryServicePrincipal认证方式:直接升级本地ODBC驱动到17以上版本 - 连接超时:先检查Azure SQL防火墙是否放通了你当前客户端的公网IP,以及本地网络有没有限制1433端口出站
- 认证无效:检查Service Principal的客户端密钥是否过期,密钥值复制的时候有没有多带空格
内容的提问来源于stack exchange,提问作者Sharayu Dhamale
相关产品推荐
相关产品推荐

