“未指定驱动程序名称”将 pandas 数据帧写入 SQL Server 表

Posted

技术标签:

【中文标题】“未指定驱动程序名称”将 pandas 数据帧写入 SQL Server 表【英文标题】:"No driver name specified" writing pandas data frame into SQL Server table 【发布时间】:2017-03-12 22:53:55 【问题描述】:

我正在尝试将 Pandas 的 DataFrame 写入 SQL Server 表。这是我的例子:

import pyodbc
import pandas as pd
import sqlalchemy

df = pd.DataFrame('MDN': [242342342] )
engine = sqlalchemy.create_engine('mssql://localhost/Sandbox?trusted_connection=yes')
df.to_sql('Test',engine, if_exists = 'append',index = False)

我收到以下错误消息。关于如何解决的任何想法?

c:\python34\lib\site-packages\sqlalchemy\connectors\pyodbc.py:82: SAWarning: No driver name specified; this is expected by PyODBC when using DSN-less connections
  "No driver name specified; "


---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-25-78677a18ce2d> in <module>()
      4 engine = sqlalchemy.create_engine('mssql://localhost/Sandbox?trusted_connection=yes')
      5 
----> 6 df.to_sql('Test',engine, if_exists = 'append',index = False)
      7 
      8 #cnxn.close()

c:\python34\lib\site-packages\pandas\core\generic.py in to_sql(self, name, con, flavor, schema, if_exists, index, index_label, chunksize, dtype)
    980             self, name, con, flavor=flavor, schema=schema, if_exists=if_exists,
    981             index=index, index_label=index_label, chunksize=chunksize,
--> 982             dtype=dtype)
    983 
    984     def to_pickle(self, path):

c:\python34\lib\site-packages\pandas\io\sql.py in to_sql(frame, name, con, flavor, schema, if_exists, index, index_label, chunksize, dtype)
    547     pandas_sql.to_sql(frame, name, if_exists=if_exists, index=index,
    548                       index_label=index_label, schema=schema,
--> 549                       chunksize=chunksize, dtype=dtype)
    550 
    551 

c:\python34\lib\site-packages\pandas\io\sql.py in to_sql(self, frame, name, if_exists, index, index_label, schema, chunksize, dtype)
   1564                             if_exists=if_exists, index_label=index_label,
   1565                             dtype=dtype)
-> 1566         table.create()
   1567         table.insert(chunksize)
   1568 

c:\python34\lib\site-packages\pandas\io\sql.py in create(self)
    646 
    647     def create(self):
--> 648         if self.exists():
    649             if self.if_exists == 'fail':
    650                 raise ValueError("Table '%s' already exists." % self.name)

c:\python34\lib\site-packages\pandas\io\sql.py in exists(self)
    634 
    635     def exists(self):
--> 636         return self.pd_sql.has_table(self.name, self.schema)
    637 
    638     def sql_schema(self):

c:\python34\lib\site-packages\pandas\io\sql.py in has_table(self, name, schema)
   1577         query = flavor_map.get(self.flavor)
   1578 
-> 1579         return len(self.execute(query, [name,]).fetchall()) > 0
   1580 
   1581     def get_table(self, table_name, schema=None):

c:\python34\lib\site-packages\pandas\io\sql.py in execute(self, *args, **kwargs)
   1465             cur = self.con
   1466         else:
-> 1467             cur = self.con.cursor()
   1468         try:
   1469             if kwargs:

AttributeError: 'Engine' object has no attribute 'cursor'

另外,有没有办法以不同的方式为create_engine 编写连接字符串?我很想用字典而不是字符串的形式来写它。

更新:这是我的新环境:

MS SQL Server:Microsoft SQL Server 2012 - 11.0.2100.60 (X64) 2012 年 2 月 10 日 19:39:15 版权所有 (c) 微软公司 Windows NT 6.2(内部版本 9200:)上的标准版(64 位)

Python:3.4.3(v3.4.3:9b73f1c3e601,2015 年 2 月 24 日,22:43:06)[MSC v.1600 32 位(英特尔)]

熊猫版本:'0.16.2'

sqlalchemy 版本:1.1.3

Jupyter 服务器版本:4.2.3

现在行

engine = sqlalchemy.create_engine('mssql+pyodbc://localhost/Sandbox?trusted_connection=yes')

产生以下错误:

c:\python34\lib\site-packages\sqlalchemy\connectors\pyodbc.py:82: SAWarning: No driver name specified; this is expected by PyODBC when using DSN-less connections
  "No driver name specified; "

【问题讨论】:

所以没有办法将数据帧转储到 SQL Server 的表中? 能否提供您的版本:MS SQL Server 版本、Pandas 版本、SQLAlchemy 版本? 试试df.to_sql('Test', engine.connect(), if_exists='append', index=False) @GordThompson,因为 pandas 0.14 这不是正确的做法:***.com/a/26766205/2230844 @user1700890,请参阅cco's answer - 我认为它完全回答了您的问题 【参考方案1】:

您需要指定要使用 ODBC 以及要使用的 ODBC 驱动程序。

engine = sqlalchemy.create_engine('mssql+pyodbc://localhost/Sandbox?driver=SQL+Server+Native+Client+11.0')

受信任的连接是默认连接,因此您不需要指定它,尽管这样做应该没有什么坏处。

更新: 2022-02-18:SQL Server 的最新 ODBC 驱动程序似乎是“SQL Server 的 ODBC 驱动程序 17”。名为“SQL Server”的驱动程序太旧,不应使用。 @user1718097 提供了有用的建议,即使用 [x for x in pyodbc.drivers()] 列出已安装的驱动程序。 您还可以在 powershell 中使用Get-OdbcDriver cmdlet 列出已安装的驱动程序。

【讨论】:

根据此答案和 sqlalchemy 文档,仅在自定义时才需要驱动程序:***.com/a/25662997/2230844 如果您不使用 DSN,则需要驱动程序 - 请参阅问题中的最后一条错误消息。 @cco 非常感谢您的回答!是否可以用字典格式编写它。另外,如果我需要提供登录名和密码,我该怎么做? 将字符串中的localhost 更改为user:password@localhost 应该是正确的。如果这不起作用,附加 ;User Id=myUsername; Password=myPassword; 应该可以解决问题。我不确定您所说的“字典格式”是什么意思。 当我尝试这个时,我不确定我的计算机上安装了哪些 OBDC 驱动程序。导入 pyodbc 后,我运行 [x for x in pyodbc.drivers()] 以获取已安装驱动程序的列表。就我而言,只有['SQL Server'],所以我能够包含driver=SQL+Server,一切正常。【参考方案2】:

可能的问题是你没有指定驱动,所以试试:

engine = sqlalchemy.create_engine('mssql+pyodbc://localhost/Sandbox?trusted_connection=yes')

这是基于您在顶部收到的警告消息:

c:\python34\lib\site-packages\sqlalchemy\connectors\pyodbc.py:82: SAWarning: No driver name specified; this is expected by PyODBC when using DSN-less connections
  "No driver name specified; "

请注意,您也可以使用 pymssql 代替 pyodbc,但 MS 建议使用后者。


编辑


以下是有关如何使用/不使用 DSN(数据源名称)进行连接的官方文档:

https://github.com/mkleehammer/pyodbc/blob/master/docs/index.md#connect-to-a-database

【讨论】:

我的环境略有变化,但原代码和你的建议,我得到了同样的错误c:\python34\lib\site-packages\sqlalchemy\connectors\pyodbc.py:82: SAWarning: No driver name specified; this is expected by PyODBC when using DSN-less connections "No driver name specified; "【参考方案3】:

我知道这个问题已经回答了一段时间了,这只是一个警告,但是如果您正确传输了所有内容并且仍然出现此错误,那就很烦人了。

对于所有像我一样苦苦挣扎的人,您也可以直接在脚本中输入驱动程序,Pyodbc.py 提供了这种可能性(第 26 - 28 行):

    # for non-DSN connections, this *may* be used to
    # hold the desired driver name
    pyodbc_driver_name = 'ODBC Driver 17 for SQL Server'

【讨论】:

【参考方案4】:

以上信息非常有用。将我的以下版本评论为合并版本,这可以在搜索过程中帮助新人。

#using library pandas 和 pyodbc - 如果不可用,请使用 pip install 命令根据版本安装库。这里使用的 Python 版本是 3.7.8

import pandas as pd
from sqlalchemy import create_engine
import pyodbc
 
  
#This query will work for sql authentication
def mssql_engine():
    engine = create_engine('mssql+pyodbc://type_username:type_password@type_servername_or_localhostname/type_database_name?driver=SQL+Server+Native+Client+11.0')
    return engine

#This query will for windows authentication 
#Note: Uncomment below code for windows authentication
#def mssql_engine():
      #engine = create_engine('mssql+pyodbc://localhostname/db_name?driver=SQL+Server+Native+Client+11.0')
      #return engine
   
 
query = 'select * from table_name'
#using pandas to read from sql and passing connection string as function
df = pd.read_sql(query, mssql_engine() ) 

#printing result
print(df)

【讨论】:

以上是关于“未指定驱动程序名称”将 pandas 数据帧写入 SQL Server 表的主要内容,如果未能解决你的问题,请参考以下文章

将大型 Pandas 数据帧写入 SQL Server 数据库

将数据从 python pandas 数据帧导出或写入 MS Access 表

将列表写入 pandas 数据帧到 csv,从 csv 读取数据帧并再次转换为列表而无需字符串

有效地将Pandas数据帧写入Google BigQuery

高效地将大型 Pandas 数据帧读取到磁盘

AWS:从 Pandas 数据帧写入 DynamoDB