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

Django执行PrintCSV视图时SQL Server提示master数据库登录失败如何解决

问题结论

该报错核心是代码逻辑错误导致,并非你配置的登录权限有问题,权限配置是正常的。

具体错误原因
    1. 拼接数据库连接串时错误使用了字典对象转字符串作为库名
      你提前把获取到的数据库名存成了{'name': 库名}格式的字典,遍历的时候直接用str(x)拼接,得到的是"{'name': 'master'}"这种字符串,导致程序尝试打开一个名字叫'name': 'master'的不存在的数据库,直接触发登录失败报错。
    1. 连接串参数写法错误触发无效属性告警
      SQL Server的ODBC驱动不支持单独写PORT=xxx参数,正确写法是把端口拼到SERVER字段后,格式为SERVER=IP,端口,你单独加的PORT参数就是报错里Invalid connection string attribute的来源。
    1. 查询用错了数据库连接对象
      你遍历每个库的时候新建了connect连接对象,但执行查询的时候仍然用了最开始的cnxn连接(仅连了默认库),即使第一个问题解决,也查不到对应库的数据。
    1. 字典取值方式错误
      你把查询结果存成了键为Account、Balance的字典,但后续取值用了列表的索引写法rdict[0]、rdict[1],运行到这一步也会抛出KeyError报错。
修正后的代码示例
import pyodbc
import csv
from django.http import HttpResponse

def PrintCSV(request):
    # 获取所有数据库名
    cnxn = pyodbc.connect('DRIVER={SQL Server};'
                          'SERVER=serverIP,port;' # 端口写到SERVER后面用逗号分隔
                          'UID=kyle_dev_ro;'
                          'PWD=password;')

    databaseName = 'SELECT name FROM sys.databases'
    cursor = cnxn.cursor()
    cursor.execute(databaseName)
    XdatabaseNames = cursor.fetchall()
    cursor.close()
    cnxn.close() # 用完就关连接
    
    dbNames= [row[0] for row in XdatabaseNames] # 直接存库名字符串就行,不用转字典

    # 初始化CSV
    response = HttpResponse(content_type='text/csv')
    response['Content-Disposition'] = 'attachment; filename="Avonlea_file.csv"'
    writer = csv.writer(response)
    writer.writerow(['Unit', 'Balance'])

    for db_name in dbNames:
        # 连接对应数据库
        connect = pyodbc.connect('DRIVER={SQL Server};'
                                 'SERVER=192.168.1.1,1433;' # 去掉单独的PORT参数
                                 'Database=' + db_name + ';' # 直接用库名字符串
                                 'UID=kyle_dev_ro;'
                                 'PWD=fh$sa#8d#7F8Y3;')

        XaccAreas = " SELECT Account, DCBalance FROM [dbo].[Client] where iAgeingTermID = '3' AND DCBalance < 0 "
        cursor = connect.cursor() # 用当前库的连接创建游标
        cursor.execute(XaccAreas)
        accAreas = cursor.fetchall()
        cursor.close()
        connect.close()
        
        for account, balance in accAreas:
            # 不需要转字典,直接用元组取值就行
            writer.writerow([
                '',
                db_name,
                '',
            ])
            writer.writerow([
                account,
                balance,
            ])

    return response
额外注意事项
  • 你可以根据实际需求调整CSV的行写入逻辑,现在的写法每个账户前面都会多写一行只有库名的空行,确认是否符合你的导出要求。
  • 如果有不需要遍历的系统库(比如master、tempdb、model、msdb),可以在遍历dbNames的时候加过滤条件跳过,避免无意义的连接查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 12:18:02