部署在Heroku的Django无法连接MSSQL Server(ODBC驱动17)求助
Heroku部署Django+MSSQL连接失败解决方案
问题背景
在Heroku部署以MSSQL Server 2014为数据库的Django项目时,使用ODBC Driver 17 for SQL Server无法建立连接,报错:pyodbc.OperationalError: ('08001', '[08001] [Microsoft][ODBC Driver 17 for SQL Server]Client unable to establish connection (0) (SQLDriverConnect)')。已确认驱动与SQL Server 2014兼容,相关配置如下:
相关配置
requirements.txt
asgiref Django==4.0 pytz sqlparse djangorestframework gunicorn python-dotenv django-mssql-backend whitenoise pyodbc
环境变量
ENGINE: sql_server.pyodbc
settings.py数据库配置
'default': { 'ENGINE': os.getenv('ENGINE'), 'NAME': os.getenv('NAME'), 'USER': os.getenv('USER'), 'PASSWORD': os.getenv('PASSWORD'), 'HOST': os.getenv('DATABASE_HOST'), "OPTIONS": { "driver": "ODBC Driver 17 for SQL Server", } },
Aptfile
unixodbc unixodbc-dev
Buildpacks顺序
- https://github.com/heroku/heroku-buildpack-apt.git
- https://github.com/heroku/heroku-buildpack-python.git
- https://github.com/matt-bertoncello/python-pyodbc-buildpack.git
排查与解决方案
1. 验证数据库网络可达性
- 确认MSSQL服务器防火墙允许Heroku节点访问,或临时开放公网访问权限(注意安全边界)
- 检查
DATABASE_HOST是否包含正确端口:MSSQL默认端口为1433,非默认端口需在HOST后追加,端口号,例如your-server.database.windows.net,1433
2. 补充ODBC连接参数
在settings.py的OPTIONS中添加适配参数,解决SQL Server 2014与Heroku环境的兼容性问题:
"OPTIONS": { "driver": "ODBC Driver 17 for SQL Server", "extra_params": "Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;", "MARS_Connection": "True" }
Encrypt=yes:适配现代SQL Server的加密传输要求TrustServerCertificate=no:严格验证服务器证书(若证书不可信,可临时设为yes排查)Connection Timeout=30:延长超时时间,抵消Heroku网络波动影响
3. 修复Django与后端版本兼容
Django 4.0与django-mssql-backend 2.8.1存在兼容性冲突,调整版本:
修改requirements.txt:
Django==3.2.20 django-mssql-backend==3.2.0
4. 验证ODBC驱动安装状态
在Heroku控制台执行命令,确认驱动是否正确部署:
odbcinst -q -d
若输出未包含ODBC Driver 17 for SQL Server,重新检查Buildpack顺序,确保python-pyodbc-buildpack在Python Buildpack之后执行
5. 确认数据库认证权限
- 若使用SQL Server身份认证,核对
USER、PASSWORD变量,确保该用户拥有目标数据库的读写权限 - Heroku环境不推荐使用Windows身份认证,若必须使用,需在连接参数中添加
Trusted_Connection=yes
6. 直接测试pyodbc连接
在Heroku控制台进入Python shell,跳过Django直接测试连接,定位问题根源:
import os import pyodbc conn = pyodbc.connect( 'DRIVER={ODBC Driver 17 for SQL Server};' 'SERVER=' + os.getenv('DATABASE_HOST') + ';' 'DATABASE=' + os.getenv('NAME') + ';' 'UID=' + os.getenv('USER') + ';' 'PWD=' + os.getenv('PASSWORD') + ';' 'Encrypt=yes;TrustServerCertificate=no;' ) cursor = conn.cursor() cursor.execute("SELECT @@VERSION") print(cursor.fetchone())
若此连接失败,说明问题出在网络或数据库配置,而非Django框架本身
内容的提问来源于stack exchange,提问作者Musab Gulfam
相关产品推荐
相关产品推荐

