通过 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为例)

Sage 50 的 Pyodbc 到 SQLAlchemy 连接字符串

SqlAlchemy 等效于使用 FreeTDS 的 pyodbc 连接字符串