背景
在windows上使用pymssql连接SQLServer数据库是正常的,但是在linux服务器上使用pymssql连接SQLServer数据库的时候报了下面这个错误:
File "/home/hcp360/.local/lib/python3.7/site-packages/sqlalchemy/util/compat.py", line 211, in raise_
raise exception
File "/home/hcp360/.local/lib/python3.7/site-packages/sqlalchemy/pool/base.py", line 599, in __connect
connection = pool._invoke_creator(self)
File "/home/hcp360/.local/lib/python3.7/site-packages/sqlalchemy/engine/create.py", line 578, in connect
return dialect.connect(*cargs, **cparams)
File "/home/hcp360/.local/lib/python3.7/site-packages/sqlalchemy/engine/default.py", line 558, in connect
return self.dbapi.connect(*cargs, **cparams)
File "src/pymssql.pyx", line 642, in pymssql.connect
sqlalchemy.exc.OperationalError: (pymssql.OperationalError) (20002, b'DB-Lib error message 20002, severity 9:\nAdaptive Server connection failed (xxx.xxx.com)\n')
(Background on this error at: http://sqlalche.me/e/14/e3q8)
下面为测试连接代码:
# -*-coding:utf-8-*-
import pymssql
from sqlalchemy import create_engine
# 获取数据库连接
engine = create_engine('mssql+pymssql://username:password@192.168.1.1:1433/database?charset=utf8')
# 打印读取结果
print(engine.execute("SELECT * from test").fetchall())
所使用的python和pymssql版本:
python:3.7.9
pymssql:2.1.5
步骤
通过查阅官方文档,发现可以通过添加TDSDUMP打印更详细的pymssql操作数据库日志来定位问题:
import os
os.environ['TDSDUMP'] = 'stdout'
在添加详细的日志打印之后,发现windows上和linux上二者的打印日志有些区别,左侧为linux下连接的日志,右侧为windows下连接的日志,可以看到:windows下多了ssl相关的处理:
到此,问题很有可能是由于linux下的pymssql没有进行ssl处理,导致连接不到数据库。
通过查阅资料发现pymssql在windows下对ssl是有支持的,但是在linux下需要自己安装对应的freetds模块,再安装pymssql才会有ssl支持。
不过我并没有自己去重新安装freetds和pymssql,因为通过在docker中linux上去尝试使用最新版本的pymssql时,发现最新的pymssql:2.2.0自带了ssl功能。所以只需要重新安装服务器上的pymssql到最新版本即可。
# 执行下这个命令卸载原来的pymssql
sudo pip3 uninstall pymssql
#再执行下面这个命令安装新版的pymssql
sudo pip3 install "pymssql=="2.2.0"
至此,linux上的pymssql也可能成功连接到数据库了。
参考
Adaptive server connection failed (DB-Lib error message 20002, severity 9)
python - Can Pymssql have a secure connection (SSL) to MS SQL Server?
Can Pymssql have a secure connection (SSL) to MS SQL Server?
FreeTDS fails to connect to SQL Server after recent Windows patches and TLS1 being disabled