使用 sqlalchemy 和 pyodbc 连接到 SQL Server 2012

Posted

技术标签:

【中文标题】使用 sqlalchemy 和 pyodbc 连接到 SQL Server 2012【英文标题】:Connecting to SQL Server 2012 using sqlalchemy and pyodbc 【发布时间】:2013-03-22 22:57:14 【问题描述】:

我正在尝试在 Python 3.3(Windows 7-64 位)上使用 SQLAlchemy(带有 pyodbc)连接到 SQL Server 2012 数据库。我可以使用直接 pyodbc 进行连接,但使用 SQLAlchemy 连接失败。我已经为数据库访问设置了 dsn 文件。

我像这样使用直接 pyodbc 成功连接:

con = pyodbc.connect('FILEDSN=c:\\users\\me\\mydbserver.dsn')

对于我尝试过的 sqlalchemy:

import sqlalchemy as sa
engine = sa.create_engine('mssql+pyodbc://c/users/me/mydbserver.dsn/mydbname')

create_engine 方法实际上并没有建立连接并成功,但是 i如果我尝试一些导致 sqlalchemy 实际设置连接的方法(如 engine.table_names()),它需要一段时间但随后返回此错误:

DBAPIError: (Error) ('08001', '[08001] [Microsoft][ODBC SQL Server Driver][DBNETLIB]SQL Server does not exist or access denied. (17) (SQLDriverConnect)') None None

我不确定哪里出了问题,如何查看 sqlalchemy 实际将什么连接字符串传递给 pyodbc。我已经成功地在 SQLite 和 mysql 中使用了相同的 sqlalchemy 类。

提前致谢!

【问题讨论】:

我发现 SQLAlchemy 文档在这个主题上严重不足。有必要进行改进。 【参考方案1】:

SQLAlchemy 将基于文件的 DSN 字符串解释为服务器名称 = c,数据库名称 = users

我更喜欢在不使用 DSN 的情况下进行连接,在代码迁移期间需要处理的配置任务更少。

此语法使用 Windows 身份验证:

engine = sa.create_engine('mssql+pyodbc://server/database')

或使用 SQL 身份验证:

engine = sa.create_engine('mssql+pyodbc://user:password@server/database')

SQLAlchemy 对不同的连接字符串选项here 有详尽的解释。

【讨论】:

谢谢。 SQL Server 实例是唯一不在我正在处理的机器上的实例,所以我不确定这里是否发生了一些有趣的事情。只是为了稍微扩展一下您列出的问题(因为显然命名了 sql server 实例)-sa.create_engine('mssql+pyodbc://[machinename]\\[servername]/[database]') 他们不必被命名。实际上,连接和使用配置为“默认实例”的 sql server 实例更容易。当您将在一台服务器上托管多个 sql server 实例时,需要命名实例。 该链接已损坏。我认为这是一个合适的替代品:docs.sqlalchemy.org/en/latest/core/engines.html#database-urls engine = sa.create_engine('mssql+pyodbc://user:password@server/database') 你必须添加这个?driver=SQL+Server+Native+Client+11.0所以最终将是engine = sa.create_engine('mssql+pyodbc://user:password@server/database?driver=SQL+Server+Native+Client+11.0') @Bryan 参考你提到的语法engine = sa.create_engine('mssql+pyodbc://user:password@server/database'),如果密码里面有@怎么办?我能做些什么?它被炼金术错误地解析了。编辑:在文档链接中找到了解决方案,可以选择将字符串直接传递给 pyodbc 以避免误解。【参考方案2】:

在 Python 3 中,您可以使用模块 urllib.parse 中的函数 quote_plus 来创建连接参数:

import urllib
params = urllib.parse.quote_plus("DRIVER=SQL Server Native Client 11.0;"
                                 "SERVER=dagger;"
                                 "DATABASE=test;"
                                 "UID=user;"
                                 "PWD=password")

engine = sa.create_engine("mssql+pyodbc:///?odbc_connect=".format(params))

为了使用 Windows 身份验证,您希望使用 Trusted_Connection 作为参数:

params = urllib.parse.quote_plus("DRIVER=SQL Server Native Client 11.0;"
                                 "SERVER=dagger;"
                                 "DATABASE=test;"
                                 "Trusted_Connection=yes")

在 Python 2 中,您应该改用库 urllib 中的函数 quote_plus

params = urllib.quote_plus("DRIVER=SQL Server Native Client 11.0;"
                           "SERVER=dagger;"
                           "DATABASE=test;"
                           "UID=user;"
                           "PWD=password")

【讨论】:

对于python 3,我们应该使用urllib.parse.quote_plus【参考方案3】:

我有一个关于在不使用 DSN 和使用 Windows 身份验证的情况下连接到 MSSQL Server 的更新信息。在我的示例中,我有下一个选项: 我的本地服务器名称是“(localdb)\ProjectsV12”。我从数据库属性中看到的本地服务器名称(我使用的是 Windows 10 / Visual Studio 2015)。 我的数据库名称是“MainTest1”

engine = create_engine('mssql+pyodbc://(localdb)\ProjectsV12/MainTest1?driver=SQL+Server+Native+Client+11.0', echo=True)

需要指定连接的驱动程序。 您可以在以下位置找到您的客户端版本:

控制面板>系统和安全>管理工具。>ODBC 数据 来源>系统 DSN 选项卡>添加

从列表中查看 SQL Native 客户端版本。

【讨论】:

这是唯一对我有用的。非常感谢! 在我的情况下?driver=SQL+Server+Native+Client+11.0 是我正在寻找的字符串位。太懒了,找不到我的旧代码:D @SupunDeSilva 这正是我自己所需要的。太感谢了。我希望我能对您的评论和安德鲁的回答投票 10000 次。 注意,*NIX 系统上的其他驱动程序位置也可以正常工作。在 OSX 上,我使用了 driver=/usr/local/lib/libtdsodbc.so【参考方案4】:

只想在这里添加一些最新信息: 如果您使用 DSN 连接进行连接:

engine = create_engine("mssql+pyodbc://USERNAME:PASSWORD@SOME_DSN")

如果您使用主机名连接进行连接:

engine = create_engine("mssql+pyodbc://USERNAME:PASSWORD@HOST_IP:PORT/DATABASENAME?driver=SQL+Server+Native+Client+11.0")

更多详情请参考"Official Document"

【讨论】:

这个答案帮助了我,但只是补充说,如果有人提到port,那么它应该作为hostname,port而不是hostname:port给出。 mssql 需要逗号而不是冒号。 @shshnk,我在我的 Mac 上检查了 hostname,porthostname:port,两者都有效。 我很惊讶: 起作用了。对于 sql server,即使您在这里看到 ***.com/questions/5294721/… 。答案是使用,。我正在使用ODBC+Driver+17+for+SQL+Server,如果这有什么不同的话。 @shshnk 逗号以某种方式自动翻译,它被视为主机名的一部分,我相信这就是这两种解决方案都有效的原因【参考方案5】:
import pyodbc 
import sqlalchemy as sa
engine = sa.create_engine('mssql+pyodbc://ServerName/DatabaseName?driver=SQL+Server+Native+Client+11.0',echo = True)

这适用于 Windows 身份验证。

【讨论】:

【参考方案6】:

我做了不同的事情,并且像个魅力人一样工作。

首先你导入库:

import pandas as pd
from sqlalchemy import create_engine
import pyodbc

创建一个函数来创建引擎

def mssql_engine(user = os.getenv('user'), password = os.getenv('password')
                 ,host = os.getenv('SERVER_ADDRESS'),db = os.getenv('DATABASE')):
    engine = create_engine(f'mssql+pyodbc://user:password@host/db?driver=SQL+Server')
    return engine

使用您的查询创建一个变量

query = 'SELECT * FROM [Orders]'

执行 Pandas 命令从 MSSQL 表创建数据框

df = pd.read_sql(query, mssql_engine())

【讨论】:

以上是关于使用 sqlalchemy 和 pyodbc 连接到 SQL Server 2012的主要内容,如果未能解决你的问题,请参考以下文章

Sage 50 的 Pyodbc 到 SQLAlchemy 连接字符串

使用 sqlalchemy.engine.url.URL 为 mssql+pyodbc 构建连接 URL

sqlalchemy 无法连接到 ms sql server

SQLAlchemy - MS Access 连接失败

将 sqlalchemy 连接到 MS Access

Python数据库编程(以pyodbc和SQLAlchemy为例)