尝试使用 pyodbc 连接到 SQL Server 数据库时出现操作错误

发布于 2025-01-16 11:49:47 字数 661 浏览 5 评论 0 原文

我正在尝试使用 Python 3 中的 pyodbc 连接到 SQL Server 数据库。但是当我尝试建立连接时出现错误。

我做了这样的事情:

import pyodbc
conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};Server=192.168.2.250;Database=DB;UID=username;PWD=password;')

我得到这个:

OperationalError: ('08001', '[08001] [Microsoft][ODBC Driver 18 for SQL Server]SSL Provider: [error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol][error:140B40C7:SSL routines:SSL_do_handshake:peer did not return a certificate] (-1) (SQLDriverConnect)')

有人知道如何解决这个问题吗?该数据库不是我自己的,所以我希望有一个不需要更改任何设置的解决方案。

我在 Linux 的 Windows 子系统中运行 Ubuntu。

I'm trying to connect to a SQL server database using pyodbc in Python 3. But I get an error when I'm trying to establish the connection.

I do something like this:

import pyodbc
conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};Server=192.168.2.250;Database=DB;UID=username;PWD=password;')

And I get this:

OperationalError: ('08001', '[08001] [Microsoft][ODBC Driver 18 for SQL Server]SSL Provider: [error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol][error:140B40C7:SSL routines:SSL_do_handshake:peer did not return a certificate] (-1) (SQLDriverConnect)')

Does anybody know how to solve this? The database is not my own, so I hope there is a solution that doesn't require changing any settings there.

I'm running Ubuntu within the Windows Subsystem for Linux.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

荒人说梦 2025-01-23 11:49:47

有一个

与几年前网络浏览器中 HTTP 到 HTTPS 默认更改(及其安全原因)类似,我们正在更改 Encrypt 连接选项的默认值 /强制

适用于 SQL Server 的 ODBC 驱动程序 18.0 已发布

因此这

conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};Server=192.168.2.250;Database=DB;UID=username;PWD=password;')

相同

conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};Server=192.168.2.250;Database=DB;UID=username;PWD=password;Encrypt=yes')

与如果您不想要加密连接则必须选择退出

conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};Server=192.168.2.250;Database=DB;UID=username;PWD=password;Encrypt=no')

我们还更改了 TrustServerCertificate 的行为,使其不与加密设置绑定

因此,如果您的服务器使用自签名证书,您还必须选择退出证书验证。所以

conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};Server=192.168.2.250;Database=DB;UID=username;PWD=password;Encrypt=no;TrustServerCertificate=yes')

There is a breaking change in ODBC Driver 18 for SQL Server

Similar to the HTTP to HTTPS default changes made in web browsers a few years back (and the security reasons for them), we are changing the default value of the Encrypt connection option from no to yes/mandatory.

ODBC Driver 18.0 for SQL Server Released

So this

conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};Server=192.168.2.250;Database=DB;UID=username;PWD=password;')

is the same as

conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};Server=192.168.2.250;Database=DB;UID=username;PWD=password;Encrypt=yes')

If you don't want an encrypted connection you must opt out:

conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};Server=192.168.2.250;Database=DB;UID=username;PWD=password;Encrypt=no')

We also changed the behavior of TrustServerCertificate to not be tied to the Encrypt setting

So if your server is using a self-signed certificate, you also must opt out of certificate validation. so

conn = pyodbc.connect('Driver={ODBC Driver 18 for SQL Server};Server=192.168.2.250;Database=DB;UID=username;PWD=password;Encrypt=no;TrustServerCertificate=yes')
谈场末日恋爱 2025-01-23 11:49:47

我最终从 WSL 中取出了我的脚本。在我的例子中,在 Windows 下运行相同的命令(使用 David 的添加或 ODBC Driver 17 for SQL Server 而不是 18)可以正常工作。

I ended up taking my script out of WSL. Running the same command (with David's additions or ODBC Driver 17 for SQL Server instead of 18) under Windows works without issues in my case.

梦与时光遇 2025-01-23 11:49:47

我使用了 pyodbc 库,但不断出现错误。使用 pymssql 对我有用:

import pymssql
conn = pymssql.connect(server='172.30.1.19')
cursor = conn.cursor()
cursor.execute(query)
rows = cursor.fetchall()

不需要端口、用户名和密码

I used the pyodbc library, but kept getting errors. Using pymssql worked for me:

import pymssql
conn = pymssql.connect(server='172.30.1.19')
cursor = conn.cursor()
cursor.execute(query)
rows = cursor.fetchall()

No need for port, username and password

泪之魂 2025-01-23 11:49:47

对于 2016 年之前的 SQL Server,请尝试使用 JDCB 驱动程序而不是 ODBC 驱动程序。

Maven JDBC:

com.microsoft.sqlserver:mssql-jdbc:8.4.1.jre8

Python / Pyspark 代码:

jdbcHostname = "SERVER_NAME"
jdbcPort = 1433
jdbcDatabase = "DATABASE_NAME"
jdbcUsername = "USERNAME"
jdbcPassword = "PASSWORD"

jdbcUrl = f"jdbc:sqlserver://{jdbcHostname}:{jdbcPort};database={jdbcDatabase}"

connectionProperties = {
    "user": jdbcUsername,
    "password": jdbcPassword,
    "driver": "com.microsoft.sqlserver.jdbc.SQLServerDriver"
}

df = spark.read.jdbc(url=jdbcUrl, table="TABLE_NAME", properties=connectionProperties)

For SQL Servers older than 2016, try using JDCB driver instead of ODBC driver.

Maven JDBC:

com.microsoft.sqlserver:mssql-jdbc:8.4.1.jre8

Python / Pyspark code:

jdbcHostname = "SERVER_NAME"
jdbcPort = 1433
jdbcDatabase = "DATABASE_NAME"
jdbcUsername = "USERNAME"
jdbcPassword = "PASSWORD"

jdbcUrl = f"jdbc:sqlserver://{jdbcHostname}:{jdbcPort};database={jdbcDatabase}"

connectionProperties = {
    "user": jdbcUsername,
    "password": jdbcPassword,
    "driver": "com.microsoft.sqlserver.jdbc.SQLServerDriver"
}

df = spark.read.jdbc(url=jdbcUrl, table="TABLE_NAME", properties=connectionProperties)
梦行七里 2025-01-23 11:49:47

这超出了原来问题的范围。最好是对 @david-browne-microsoft 的答案的评论,但我还不能发表评论。

对于那些使用 sqlalchemy 的用户(尤其是 1.4 之前的版本,没有 sqlalchemy.engine.URL.create 方法,否则请参阅 如何使用 SQLAlchemy create_engine() 和包含 @ 的密码),您可以连接像这样:

engine = create_engine('mssql+pyodbc://{0.username}:{0.password}@{0.host}/{0.database}?Encrypt=no&TrustServerCertificate=yes&driver={0.driver}&charset=utf8&port={0.port}'.format(options))

所以 Encrypt=no&TrustServerCertificate=yes 可以简单地添加到查询参数中。我一直在相关问题的其他答案中看到 trusted_connection=yes ,但这对我不起作用。
信任这里连接的原因是它是本地主机上的一个具有自签名证书的开发数据库,​​这对于生产来说并不安全。

在我的连接字符串中,驱动程序参数应该已经经过 URL 编码,例如 'ODBC+Driver+18+for+SQL+Server'

This goes beyond the scope of the original question. Preferably it would be a comment on the answer by @david-browne-microsoft, but I can't post a comment yet.

For those using sqlalchemy (especially versions older than 1.4 that don't have sqlalchemy.engine.URL.create method, otherwise see How do I use SQLAlchemy create_engine() with password that includes an @), you can connect like this:

engine = create_engine('mssql+pyodbc://{0.username}:{0.password}@{0.host}/{0.database}?Encrypt=no&TrustServerCertificate=yes&driver={0.driver}&charset=utf8&port={0.port}'.format(options))

So Encrypt=no&TrustServerCertificate=yes can simply be added to the query parameters. I kept seeing trusted_connection=yes in other answers to related questions, but that did not work for me.
The reason for trusting the connection here is that it is a development database on localhost with self-signed certificates, this is not safe for production.

In my connection string the driver parameter should be already URL encoded, e.g. 'ODBC+Driver+18+for+SQL+Server'.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文