将 pyodbc Connection 对象与 pandas 一起使用时收到警告

新手上路,请多包涵

当我将 python 代码设置为在 VM 服务器上运行时,我试图理解以下错误,该服务器在我的桌面上安装了 3.9.5 而不是 3.8.5。不确定这是否重要,但这可能是部分原因。

错误

C:\ProgramData\Miniconda3\lib\site-packages\pandas\io\sql.py:758: UserWarning: pandas only support SQLAlchemy connectable(engine/connection) or
database string URI or sqlite3 DBAPI2 connection
other DBAPI2 objects are not tested, please consider using SQLAlchemy
  warnings.warn(

这是在一个相当简单的 .py 文件中,该文件导入了 pyodbc 和 sqlalchemy fwiw。产生警告的相当通用/简单的 sql 调用版本是:

 myserver_string = "xxxxxxxxx,nnnn"
db_string = "xxxxxx"

cnxn = "Driver={ODBC Driver 17 for SQL Server};Server=tcp:"+myserver_string+";Database="+db_string +";TrustServerCertificate=no;Connection Timeout=600;Authentication=ActiveDirectoryIntegrated;"

def readAnyTable(tablename, date):
    conn = pyodbc.connect(cnxn)

    query_result = pd.read_sql_query(
            '''
                 SELECT *
                 FROM [{0}].[dbo].[{1}]
                where Asof >= '{2}'
            '''.format(db_string,tablename,date,), conn)

    conn.close()

    return query_result

我在 python 中使用 pyodbc 看到的所有示例看起来都非常相似。 pyodbc 是否已被弃用?有没有更好的方法可以在没有警告的情况下实现类似的结果?

原文由 Josh Knechtel 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 3.8k
2 个回答

pyodbc 是否已被弃用?

至少在过去的几年里,pandas 的文档已经明确指出它需要一个 SQLAlchemy Connectable (即 EngineConnection 对象)或 SQLite DBAPI 连接。 (切换到 SQLAlchemy 几乎是普遍的,但他们继续支持 SQLite 连接以实现向后兼容性。)人们一直在通过其他 DBAPI 连接(如 pyodbc Connection 对象)进行读取操作,而 pandas 没有抱怨… 到现在。

有没有更好的方法可以在没有警告的情况下实现类似的结果?

是的。您可以采用现有的 ODBC 连接字符串并使用它来创建 SQLAlchemy Engine 对象,如 SQLAlchemy 1.4 文档 中所述:

 from sqlalchemy.engine import URL
connection_string = "DRIVER={ODBC Driver 17 for SQL Server};SERVER=dagger;DATABASE=test;UID=user;PWD=password"
connection_url = URL.create("mssql+pyodbc", query={"odbc_connect": connection_string})

from sqlalchemy import create_engine
engine = create_engine(connection_url)

然后将 engine 传递给您需要使用的 pandas 方法。

原文由 Gord Thompson 发布,翻译遵循 CC BY-SA 4.0 许可协议

    import pandas as pd
    import pyodbc
    import sqlalchemy as sa
    import urllib
    from sqlalchemy import create_engine, event
    from sqlalchemy.engine.url import URL

    server = 'IP ADDRESS or Server Name'
    database = 'AdventureWorks2014'
    username = 'xxx'
    password = 'xxx'

    params = urllib.parse.quote_plus("DRIVER={SQL Server};"
                                     "SERVER="+server+";"
                                     "DATABASE="+database+";"
                                     "UID="+username+";"
                                     "PWD="+password+";")

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

    qry = "SELECT t.[group] as [Region],t.name as [Territory],C.[AccountNumber]"
    qry = qry + "FROM [Sales].[Customer] C INNER JOIN [Sales].SalesTerritory t on t.TerritoryID = c.TerritoryID "
    qry = qry + "where StoreID is not null and PersonID is not null"

with engine.connect() as con:
    rs = con.execute(qry)

    for row in rs:
        print (row)

您可以使用 SQL Server 名称或 IP 地址,但这需要基本的 DNS 列表。大多数公司服务器应该已经有这个列表了。您可以在命令提示符中使用 nslookup 命令后跟服务器名称或 IP 地址来检查服务器名称或 IP 地址。

我在 VMWare 上运行的 Ubuntu 服务器上使用 SQL 2017。作为更广泛的“在 Ubuntu 上运行 MSSQL”项目的一部分,我在这里连接 IP 地址。

如果您使用 Windows 凭据连接,则可以将参数替换为 trusted_connection 参数。

 params = urllib.parse.quote_plus("DRIVER={SQL Server};"
                                 "SERVER="+server+";"
                                 "DATABASE="+database+";"
                                 "trusted_connection=yes")

原文由 JonTout 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进