【问题标题】:Getting a warning when using a pyodbc Connection object with pandas将 pyodbc Connection 对象与 pandas 一起使用时收到警告
【发布时间】:2022-07-14 03:11:06
【问题描述】:

我试图弄清以下错误,当我将我的 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 被弃用了吗?有没有更好的方法可以在没有警告的情况下实现类似的结果?

【问题讨论】:

    标签: sql-server python-3.x pandas pyodbc


    【解决方案1】:

    pyodbc 会被弃用吗?

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

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

    是的。您可以使用现有的 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方法。

    【讨论】:

    • 我试过并测试了它,它可以工作,谢谢!
    • 我有一个 postgresql 数据库;我正在使用 psycopg2.pool.ThreadedConnectionPool 和熊猫有问题
    • 知道为什么 pandas 团队选择不支持 DBAPI2 连接吗?鉴于 DBAPI2 的广泛使用,这似乎是一个奇怪的选择(我认为这是 Python 程序与数据库服务器通信的默认方式)
    • 错误或已弃用的导入。上面的代码 sn -p 不起作用。
    【解决方案2】:
        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")
    

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        它对我有用。

        import warnings
        
        warnings.filterwarnings('ignore')
        

        【讨论】:

          【解决方案5】:

          为 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()
          

          【讨论】:

          • @gord-thompson 我正在使用 SQLAlchemy 1.4.36,所以我不知道您为什么编辑我的答案来表达不同的意见。您上面使用的导入不起作用!
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-17
          • 1970-01-01
          • 2019-10-20
          • 2020-05-19
          • 2021-12-25
          • 2014-04-28
          相关资源
          最近更新 更多