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

使用Python的SqlManagementClient和MSAL登录时,程序化添加Azure SQL防火墙规则失败,提示'SqlManagementClient'对象无'firewall_rules'属性

使用Python的SqlManagementClient和MSAL登录时,程序化添加Azure SQL防火墙规则失败,提示'SqlManagementClient'对象无'firewall_rules'属性

问题分析

你遇到的这个错误本质上有两个核心原因:

  1. SDK版本迭代导致API结构变更:新版azure-mgmt-sql(v4.0.0+)中,直接属于SqlManagementClient的firewall_rules属性已被移除,操作入口发生了变化;
  2. 权限范围不匹配:你当前获取的令牌仅拥有数据库访问权限,但管理SQL服务器防火墙需要的是Azure资源管理器(ARM)的操作权限,两者的权限范围完全不同。

解决方案

我们需要从API调用路径和权限范围两个维度修正代码:

1. 修正防火墙规则的API调用路径

将原来的sql_client.firewall_rules替换为新版SDK的正确入口sql_client.server_firewall_rules。

2. 调整令牌的权限范围

获取交互式令牌时,使用ARM API的专属权限范围https://management.azure.com/.default,同时确保你的账号拥有SQL Server Contributor或更高权限的角色(你提到Azure Data Studio可正常使用,权限层面应该已满足)。


完整修正后的代码示例

from msal import PublicClientApplication
from azure.identity import DefaultAzureCredential
from azure.mgmt.sql import SqlManagementClient
import pyodbc
import requests

# 替换为你的Azure资源配置信息
tenant_id = "your-tenant-id"
client_id = "your-client-id"
subscription_id = "your-subscription-id"
resource_group_name = "your-resource-group"
sql_server_name = "your-sql-server-name"
firewall_rule_name = "Notebook-Temp-IP-Rule"  # 自定义防火墙规则名称
server = f"{sql_server_name}.database.windows.net"
database = "your-database-name"

def add_firewall_rule(public_ip):
    credential = DefaultAzureCredential()
    sql_client = SqlManagementClient(credential, subscription_id)

    # 关键修正:使用新版SDK的server_firewall_rules入口
    firewall_rule = sql_client.server_firewall_rules.create_or_update(
        resource_group_name=resource_group_name,
        server_name=sql_server_name,
        firewall_rule_name=firewall_rule_name,
        parameters={
            "start_ip_address": public_ip,
            "end_ip_address": public_ip,
        }
    )
    print(f"防火墙规则已创建/更新: {firewall_rule.name}")
    return firewall_rule

# 获取ARM权限的令牌(用于管理SQL服务器资源)
app = PublicClientApplication(client_id, authority=f"https://login.microsoftonline.com/{tenant_id}")
result = app.acquire_token_interactive(scopes=["https://management.azure.com/.default"])

# 验证令牌获取是否成功
if "access_token" not in result:
    raise Exception(f"令牌获取失败: {result.get('error_description')}")

# 获取当前机器的公网IP
public_ip = requests.get("https://api.ipify.org").text
print(f"当前公网IP: {public_ip}")

# 添加防火墙规则
firewall_rule = add_firewall_rule(public_ip)

# 单独获取数据库访问令牌
db_credential = DefaultAzureCredential()
db_token = db_credential.get_token("https://database.windows.net/.default").token

# 建立数据库连接
conn = pyodbc.connect(
    f"DRIVER={{ODBC Driver 18 for SQL Server}};"
    f"SERVER={server};"
    f"DATABASE={database};"
    f"Encrypt=yes;"
    f"TrustServerCertificate=no;"
    f"AccessToken={db_token};"
)
print("数据库连接成功!")

# 示例:执行简单查询验证连接
cursor = conn.cursor()
cursor.execute("SELECT @@VERSION;")
for row in cursor.fetchall():
    print(row[0])

# 关闭资源
cursor.close()
conn.close()

额外注意事项

  • SDK版本验证:确保azure-mgmt-sql为最新稳定版,可通过pip install --upgrade azure-mgmt-sql完成更新;
  • 防火墙规则命名建议:使用带有标识性的名称(如包含当前会话特征),避免与已有规则冲突;
  • 权限隔离:建议分别获取管理资源和访问数据库的令牌,避免权限过大或范围不匹配的问题。

备注:内容来源于stack exchange,提问作者felixwcf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 08:23:03