通过 sqlalchemy 和 pyodbc 访问 MS SQL 数据库时出现“登录超时”错误
Posted
技术标签:
【中文标题】通过 sqlalchemy 和 pyodbc 访问 MS SQL 数据库时出现“登录超时”错误【英文标题】:"Login timeout expired" error when accessing MS SQL db via sqlalchemy and pyodbc 【发布时间】:2018-12-02 09:53:31 【问题描述】:所以我在让 sqlalchemy 和 pyodbc 与远程 MS SQL Server 一起工作时遇到了一些麻烦。本地 sqlcmd 工作正常,但当我尝试通过 python 代码读取数据库时却没有。任何帮助,将不胜感激。
环境:
Centos 7 SQLCmd 版本:版本 17.1.0000.1 Linux MS SQL Server 6.01.7601.17514 Python 2.7以下 sqlcmd 工作正常
sqlcmd -S Host,Port -U USER -P PWD -Q "use Database;"
尝试直接使用 sqlalchemy 或 pyodbc 无效。错误:
pyodbc.OperationalError: ('HYT00', u'[HYT00] [unixODBC][Microsoft][ODBC Driver 17 for SQL Server]登录超时已过期 (0) (SQLDriverConnect)')
代码: 尝试使用pyodbc
conn = pyodbc.connect(
r'DRIVER=ODBC Driver 17 for SQL Server;'
r'SERVER=HOST,PORT;'
r'DATABASE=DATABASE;'
r'UID=UID;'
r'PWD=PWD'
)
尝试使用 sqlalchemy:
create_engine('mssql+pyodbc://user:password@host:port/database?driver=driver'.format(
user=user,
password=password,
host=host,
database=database,
port=port,
driver="ODBC+Driver+17+for+SQL+Server"
)).connect()
如果我从命令中删除端口,我可以使用 sqlcmd 重现错误,所以我传递给 pyodbc 的 conn_string 格式可能不正确?
【问题讨论】:
我遇到了同样的问题,但在我的 Mac 机器上。唯一的区别是我使用的是 OBDC 驱动程序 13。您找到解决此问题的方法了吗? 即使我在 redhat 上使用 ODBC 驱动程序 13 时也面临同样的问题。你有解决办法吗? @Solaiman 在这里回复晚了,但下面的答案是正确的。对我来说,它最终成为了一个由拼写错误引起的 DNS 问题。在调试之前,值得先尝试 python 代码之外的端点。 【参考方案1】:问题可能与 DNS 有关,您可以阅读here。 尝试在连接字符串中使用 IP 地址而不是主机名,或检查您的 DNS 配置。
【讨论】:
localhost 在使用 mssql-cli 测试时有效,但在 python 中我必须使用环回 ip【参考方案2】:就我而言,这发生在我没有正确转义包含特殊字符的密码时。这是我的解决方案:
from urllib.parse import quote
...
passwd = 'p@ssw0rd!'
...
engine_string = f"mssql+pyodbc://user:quote(passwd)@host/name?driver=ODBC+Driver+17+for+SQL+Server"
【讨论】:
为我节省了大量时间,非常感谢! 谢谢!你救了我的命。我已经工作了 2 个小时,无法找出错误发生的原因。再次感谢!【参考方案3】:你的 python 代码是做什么的?问题可能是多个 Connections 调用。不要循环打开连接。或 conn.close() 在错误的位置。 其他问题可能是防火墙规则问题,检查一下。
我使用 pymssql 来访问我的 sql 服务器。阅读文档并在您的 centos 系统上安装 pymssql 和 freetds-dev。也许你需要编辑 freetds.conf 并添加你的 sql server 的 ip 和 port。
【讨论】:
以上是关于通过 sqlalchemy 和 pyodbc 访问 MS SQL 数据库时出现“登录超时”错误的主要内容,如果未能解决你的问题,请参考以下文章
pyodbc/sqlalchemy - 使用 pd.read_sql_query 读取表中的每一列。通过查询传递变量
使用 sqlalchemy.engine.url.URL 为 mssql+pyodbc 构建连接 URL
在 Microsoft SQL Server 和 Python 的 SQLAlchemy 和 pyodbc 的上下文中,啥是“用户事务”?
Python数据库编程(以pyodbc和SQLAlchemy为例)