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

问题描述 投票:0回答:6

我试图理解以下错误,当我将我的 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
6个回答
60
投票

pyodbc 是否已被弃用?

没有。至少在过去的几年里,pandas 的文档已经明确表示它想要任何一个

  1. a SQLAlchemy
    Connectable
    (即
    Engine
    Connection
    对象),
  2. 包含 SQLAlchemy 连接 URL 的字符串,或者
  3. a 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)

然后使用 SQLAlchemy

engine
来处理您需要的 pandas 方法,例如,

with engine.begin() as conn:
    df = pd.read_sql_query(sa.text("SELECT 'thing' as txt"), conn)

9
投票

对我有用。

import warnings

warnings.filterwarnings('ignore')

7
投票
    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
投票

因为它是一个警告,我使用警告 python 库抑制了消息。希望这有帮助

import warnings
with warnings.catch_warnings(record=True):
    warnings.simplefilter("always")
    #your code goes here

0
投票

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

python3 -W ignore

启动它

-2
投票

为 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()
© www.soinside.com 2019 - 2024. All rights reserved.