使用 pyodbc 从 WSL2 连接到 Windows 上的 SQL 服务器 - 连接超时

Connect to SQL Server on Windows from WSL2 with pyodbc - Connection Timeout

我正在尝试从 WSL2 连接到 Windows 上的 SQL 服务器,但出现连接超时错误

我正在使用这段代码:

import pyodbc
server = 'DESKTOP-LFOSSEF'
database = 'sportsanalytics'
username = 'user'
password = '{pass}'   
driver= '{ODBC Driver 17 for SQL Server}'

with pyodbc.connect('DRIVER='+driver+';SERVER=tcp:'+server+';PORT=1433;DATABASE='+database+';UID='+username+';PWD='+ password) as conn:
    with conn.cursor() as cursor:
        cursor.execute("SELECT TOP 3 name, collation_name FROM sys.databases")
        row = cursor.fetchone()
        while row:
            print (str(row[0]) + " " + str(row[1]))
            row = cursor.fetchone()

我收到以下错误:

Traceback (most recent call last): File "", line 1, in pyodbc.OperationalError: ('HYT00', '[HYT00] [Microsoft][ODBC Driver 17 for SQL Server]Login timeout expired (0) (SQLDriverConnect)')

知道如果我需要任何额外的配置来连接到安装在 Windows 上的 SQL 服务器吗?

此致

我想你很接近了。你有:

server = 'DESKTOP-LFOSSEF'

大多数人此时 localhost

但是 DESKTOP-LFOSSEF 是否从 WSL2 中正确解析?我的经验是您通常需要:

  • 主 Windows 网络适配器的 IP。临时对此进行硬编码以消除其他问题可能很有用。
  • 如果 Windows 主机有 DNS 名称,您可以使用它。如果您当前的服务器名称无法解析,您可能需要添加域。
  • Windows 主机提供给 WSL2 的虚拟路由器的 IP(ip route show default 来自 WSL 内部)
  • WSL2 中 Windows 主机的 mDNS 名称,应解析为虚拟路由器的 IP。 WSL2 自动分配 Windows“计算机名称”+“.local”域作为此地址的 mDNS 名称。

试试这个:

import pyodbc,socket
server = f'{socket.gethostname()}.local'

我设置这个已经有一段时间了,但我很确定你本地机器的名称,在本例中 DESKTOP-LFOSSEF 映射回你的 (WSL) 容器,不是主机;因为容器也被赋予相同的主机名。因此,您可以使用主机的 IP 地址,我很确定它总是 172.19.208.1.

我不记得主机在 /etc/hosts 中是否被赋予了不同的名称(我已经编辑了我的名称)所以我会先检查一下。否则你可以为你的本地主机添加一个条目或编辑一个指向主机名的主机(我就是这样做的)。

要编辑它,请在您最喜欢的命令行文本编辑器中编辑 /etc/hosts(我使用 nano,所以我会使用 sudo nano /etc/hosts),然后编辑相关行。所以我的看起来像这样:

# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateHosts = false
127.0.0.1       localhost
# 127.0.1.1     Imentet.localdomain     Imentet
172.19.208.1    imentet

其中 imentet 是我机器的名称。