sql-server 对panda使用pyodbc Connection对象时收到警告

9rnv2umw  于 2022-10-31  发布在  其他
关注(0)|答案(6)|浏览(486)

当我在VM服务器上运行python代码时,我试图弄清楚下面的错误,我的桌面上安装的是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正在被弃用吗?有没有更好的方法在没有警告的情况下实现类似的结果?

ctrmrzij

ctrmrzij1#

pyodbc正在被弃用吗?
不。至少在过去的几年里,Pandas的文档已经清楚地表明,它需要一个SQLAlchemy Connectable(即EngineConnection对象)或SQLiteDBAPI连接。(向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传递给您需要使用的panda方法。

1szpjjfi

1szpjjfi2#

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凭据进行连接,则可以将params替换为trusted_connection参数。

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

m4pnthwp3#

对我有用。

import warnings

warnings.filterwarnings('ignore')
8hhllhi2

8hhllhi24#

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

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

ggazkfy85#

我的公司不使用SQLAlchemy,而是使用基于pscycopg2的postgres连接,并结合了其他特性。如果可以直接从命令行运行脚本,那么关闭警告将解决问题:从python3 -W ignore开始

5n0oy7gb

5n0oy7gb6#

对于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()

相关问题