在 pandas 中使用 pyodbc Connection 对象时收到警告

Getting a warning when using a pyodbc Connection object with pandas

我试图弄清以下错误,当我在安装了 3.9.5 而不是 3.8 的 VM 服务器上将 python 代码设置为 运行 时开始出现以下错误。 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。产生警告的 generic/simple 版本的 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 是否已被弃用?有没有更好的方法可以在没有警告的情况下实现类似的结果?

Is pyodbc becoming deprecated?

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

Is there a better way to achieve similar results without warning?

是的。您可以获取现有的 ODBC 连接字符串并使用它来创建 SQLAlchemy Engine 对象,如 SQLAlchemy 1.4 documentation:

中所述
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方法。

我公司不使用SQLAlchemy,更喜欢使用基于pscycopg2 并结合其他功能的postgres 连接。如果您可以直接从命令行 运行 您的脚本,那么关闭警告将解决问题:使用 python3 -W ignore

启动它

为 SQLAlchemy 1.4.36 导入的正确方法是使用:

import pandas as pd
from sqlalchemy import create_engine, event
from sqlalchemy.engine.url import URL
#...

conn_str = set_db_info()    # see above
conn_url = URL.create("mssql+pyodbc", query={"odbc_connect": conn_str})
engine = create_engine(conn_url)

df = pd.read_sql(SQL, engine)
df.head()
    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 服务器名称或 IP 地址,但这需要基本的 DNS 列表。大多数公司服务器应该已经有这个列表了。您可以在命令提示符中使用 nslookup 命令后跟服务器名称或 IP 地址来检查服务器名称或 IP 地址。

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

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

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