我正在尝试通过 VSCode 中的 jupyter 笔记本查询 SQL Server 2016 数据库。为此,我按照这些说明安装 ODBC 驱动程序。
这是
odbcinst -j
命令的输出:
unixODBC 2.3.12
DRIVERS............: /usr/local/etc/odbcinst.ini
SYSTEM DATA SOURCES: /usr/local/etc/odbc.ini
FILE DATA SOURCES..: /usr/local/etc/ODBCDataSources
USER DATA SOURCES..: /Users/myname/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8
然后我在 VSCode 中运行以下 python 代码:
import pyodbc
import pandas as pd
servername = 'emp-edwh01'
dbname = 'DWH_CORE'
cnxn = pyodbc.connect('DRIVER={ODBC Driver 18 for SQL Server};SERVER='+servername+';DATABASE='+dbname)
cursor = cnxn.cursor()
query = '''SELECT * limit 100
FROM dbp.tab_CMA_CMPositions
'''
df = pd.read_sql(query, cnxn, index_col='[primary_key]')
但我看到的输出是:
OperationalError: ('08001', '[08001] [Microsoft][ODBC Driver 18 for SQL Server]Client unable to establish connection. For solutions related to encryption errors, see https://go.microsoft.com/fwlink/?linkid=2226722 (0) (SQLDriverConnect)')
我已经进行了彻底的研究(也经历了this),删除并重新安装了驱动程序,仔细检查了所有链接等。但我仍然无法连接。
另外,我在VSCode上运行连接文件时的完整日志是:
[ODBC][13195][1728651033.229336][SQLAllocHandle.c][469]
Entry:
Handle Type = 2
Input Handle = 0x7fdf0b3a6400
[ODBC][13195][1728651033.229385][SQLAllocHandle.c][585]
Exit:[SQL_SUCCESS]
Output Handle = 0x7fdeeb188e00
[ODBC][13195][1728651033.230136][SQLDriverConnectW.c][298]
Entry:
Connection = 0x7fdeeb188e00
Window Hdl = 0x0
Str In = [DRIVER={ODBC Driver 18 for SQL Server};SERVER=emp-edwh01;DATABASE=DWH_CORE][length = 74 (SQL_NTS)]
Str Out = 0x0
Str Out Max = 0
Str Out Ptr = 0x0
Completion = 0
Threading Level set from Driver Entry in ODBCINST.INI 99 from '99'
Threading Level set from [ODBC] Section in ODBCINST.INI 0 from '0'
UNICODE Using encoding ASCII 'UTF-8' and UNICODE 'UCS-2-INTERNAL'
[ODBC][13195][1728651033.367613][SQLDriverConnectW.c][870]
Exit:[SQL_ERROR]
[ODBC][13195][1728651033.367677][SQLGetDiagRecW.c][535]
Entry:
Connection = 0x7fdeeb188e00
Rec Number = 1
SQLState = 0x30a3f4824
Native = 0x30a3f4818
Message Text = 0x7fdf0c5f2e00
Buffer Length = 1023
Text Len Ptr = 0x30a3f4822
[ODBC][13195][1728651033.367732][SQLGetDiagRecW.c][596]
Exit:[SQL_SUCCESS]
SQLState = [08001]
Native = 0x30a3f4818 -> 0 (32 bits)
Message Text = [[Microsoft][ODBC Driver 18 for SQL Server]Client unable to establish connection. For solutions related to encryption errors, see]
[ODBC][13195][1728651033.367851][SQLFreeHandle.c][324]
Entry:
Handle Type = 2
Input Handle = 0x7fdeeb188e00
[ODBC][13195][1728651033.367882][SQLFreeHandle.c][373]
Exit:[SQL_SUCCESS]
编辑 - 证书
我使用 Kerberos 进行身份验证和连接。当我在 VSCode 中直接查询相同的 SQL Server 2016 时,这可以通过 Kerberos 成功运行。
我尝试运行 python 脚本来信任服务器证书:
cnxn = pyodbc.connect('DRIVER={ODBC Driver 18 for SQL Server};SERVER='+servername+';DATABASE='+dbname+';TrustServerCertificate=yes')
现在我看到的错误是:
OperationalError: ('08001', '[08001] [Microsoft][ODBC Driver 18 for SQL Server]Client unable to establish connection (0) (SQLDriverConnect)')
按照以下步骤解决。
对于 python 查询,我添加了
TrustServerCertificate=yes
和 Trusted_connection=yes
:第一个信任来自服务器的证书;第二个通过 Windows 登录名/密码进行身份验证,而不将它们作为代码中的输入。
现在最终的连接字符串是:
cnxn = pyodbc.connect('DRIVER={ODBC Driver 18 for SQL Server};SERVER='+servername+';DATABASE='+dbname+ \
';TrustServerCertificate=yes; Trusted_connection=yes')
在此之后,我确保使用正确的 OpenSSL 库版本。由于我了解到 ODBC 驱动程序不支持 OpenSSL3,因此我已切换回 OpenSSL1 并修复了所有链接。
执行此步骤后并没有立即起作用,而是需要重新启动。