Ess*_*420 6 python sql linux windows pyodbc
我正在尝试使用pyodbc从Linux机器连接到Windows SQL Server。
我确实有两个限制:
我按照Microsoft的说明设置了环境并使其正常工作(我可以导入pyodbc并使用已配置的贻贝驱动程序)。
我不熟悉Windows域身份验证,而其他方面则不熟悉,所以这里就是我的问题所在。
我的连接字符串:
DRIVER={ODBC Driver 17 for SQL Server};SERVER=myserver.mydomain.com;PORT=1433;DATABASE=MyDatabase;Domain=MyCompanyDomain;Instance=MyInstance;UID=myDomainUser;PWD=XXXXXXXX;Trusted_Connection=yes;Integrated_Security=SSPI
Run Code Online (Sandbox Code Playgroud)
假设应该使用“ Trusted_Connection”来使用Windows域身份验证,而不是直接通过SQL Server进行身份验证。
我在运行pyodbc.connect(connString)时遇到的错误:
pyodbc.Error: ('HY000', '[HY000] [unixODBC][Microsoft][ODBC Driver 17 for SQL Server]SSPI Provider: No Kerberos credentials available (851968) (SQLDriverConnect)')
Run Code Online (Sandbox Code Playgroud)
我从其他来源了解到,此代码应在Windows上运行,因为此代码将使用当前登录用户的凭据。
我的问题是如何使用Windows域凭据从Linux连接到Windows SQL Server实例。
您必须获得 Kerberos 票证才能执行此操作。您的示例没有指定您的 Linux 系统是否设置为通过 Kerberos 进行身份验证,或者您之前是否在代码命中连接字符串之前获得了 Kerberos 票证。
如果您的 Linux 系统设置为通过 Kerberos 进行身份验证,那么作为概念证明,您可以从命令行使用 kinit 获取 Kerberos 票证。这是通过 WSL 在 Windows 上的 Ubuntu 中运行的 python3 中对我有用的方法。蟒蛇代码:
#!/usr/bin/env python
# minimal example using Kerberos auth
import sys
import re
import pyodbc
driver='{ODBC Driver 17 for SQL Server}'
server = sys.argv[1]
database = sys.argv[2]
# trusted_connection uses kerberos ticket and ignores UID and PASSWORD in connection string
# https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/using-integrated-authentication?view=sql-server-ver15
try:
cnxn = pyodbc.connect(driver=driver, server=server, database=database, trusted_connection='yes')
cursor = cnxn.cursor()
except pyodbc.Error as ex:
msg = ex.args[1]
if re.search('No Kerberos', msg):
print('You must login using kinit before using this script.')
exit(1)
else:
raise
# Sample select query
cursor.execute("SELECT @@version;")
row = cursor.fetchone()
while row:
print(row[0])
row = cursor.fetchone()
print('success')
Run Code Online (Sandbox Code Playgroud)
如果您没有票,这会告诉您。由于它使用票证,因此您不必在脚本中指定用户或密码。它会忽略两者。
现在我们运行它:
user@localhost:~# kdestroy # make sure there are no active tickets
kdestroy: No credentials cache found while destroying cache
user@localhost:~# python pyodbc_sql_server_test.py tcp:dbserver.example.com mydatabase
You must login using kinit before using this script.
user@localhost:~# kinit
Password for user@DOMAIN.LOCAL:
user@localhost:~# python pyodbc_sql_server_test.py tcp:dbserver.example.com mydatabase
Microsoft SQL Server 2016 (SP2-GDR) (KB4505220) - 13.0.5101.9 (X64)
Jun 15 2019 23:15:58
Copyright (c) Microsoft Corporation
Enterprise Edition (64-bit) on Windows Server 2016 Datacenter 10.0 <X64> (Build 14393: )
success
user@localhost:~#
Run Code Online (Sandbox Code Playgroud)
您也可能成功地从在建立此连接之前运行的 python 代码获取 Kerberos 票证,但这超出了本答案的范围。搜索 python Kerberos 模块可能会为您指明解决方案。
似乎还可以设置 Linux 系统,以便在用户登录后立即自动获取可以传递给其他进程的 Kerberos 票证。这也超出了本答案的范围,但在 Linux 登录时搜索自动 Kerberos 票证可能会产生一些线索。
小智 7
我为同一任务找到了两种方法。我有带 AD 身份验证的 MSSQL 服务器。
您可以使用 JVM。加载并安装 JAVA https://www.oracle.com/technetwork/java/javase/downloads/jre8-downloads-2133155.html。还要安装 JPype1 版本 0.6.3 pip install JPype==0.6.3。0.6.3 以上的版本无法正常工作
import jaydebeapi
import pandas as pd
driver_name = "net.sourceforge.jtds.jdbc.Driver"
connection_url="jdbc:jtds:sqlserver://<server>:<port>/<database name>"
connection_properties = {
"domain": "<domain name>",
"user": "<username>",
"password": "<pwd>"}
jar_path = <path to jsds>"/jtds-1.3.1.jar"
CONN = jaydebeapi.connect(driver_name, connection_url, connection_properties, jar_path)
sql = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS"
df = pd.read_sql(sql, CONN)
Run Code Online (Sandbox Code Playgroud)
这个版本对我来说太慢了。
您也可以通过 FreeTDS使用pyodbc。创建 FreeTDS 连接 在 Linux 上安装FreeTDS,像这样apt-get install tdsodbc freetds-bin配置FreeTDS /etc/odbcinst.ini:
[FreeTDS]
Description=FreeTDS
Driver=/usr/lib/x86_64-linux-gnu/odbc/libtdsodbc.so
Setup=/usr/lib/x86_64-linux-gnu/odbc/libtdsS.so
Run Code Online (Sandbox Code Playgroud)
并打开它 odbcinst -i -d -f /etc/odbcinst.ini
之后,您可以使用pyodbc
import pandas as pd
import pyodbc
CONN =pyodbc.connect('DRIVER={FreeTDS};'
'Server=<server>;'
'Database=<database>;'
'UID=<domain name>\\<username>;'
'PWD=<password>;'
'TDS_Version=8.0;'
'Port=1433;')
sql = "SELECT * FROM INFORMATION_SCHEMA.COLUMNS"
df = pd.read_sql(sql, CONN)
Run Code Online (Sandbox Code Playgroud)
它的工作速度要快得多
我最终使用了pymssql库,该库基本上是FreeTDS驱动程序之上的pyodbc。它开箱即用。
很奇怪我很难找到这个库。
| 归档时间: |
|
| 查看次数: |
4980 次 |
| 最近记录: |