【问题标题】:to_sql pandas data frame into SQL server error: DatabaseErrorto_sql pandas 数据框进入 SQL 服务器错误:DatabaseError
【发布时间】:2018-01-01 17:19:00
【问题描述】:

在尝试将 pandas' 数据帧写入 sql-server 时,我收到此错误:

DatabaseError: 执行失败 sql 'SELECT name FROM sqlite_master WHERE type='table' AND name=?;': ('42S02', "[42S02] [Microsoft][SQL Server Native Client 11.0][SQL Server]无效的对象名称“sqlite_master”。(208) (SQLExecDirectW);[42000] [Microsoft][SQL Server Native Client 11.0][SQL Server]无法准备语句。(8180)")

似乎pandas 正在查看sqlite 而不是真正的数据库。

这不是连接问题,因为我可以使用 pandas.read_sql 以相同的连接从 sql-server 读取数据 已使用

设置连接
sqlalchemy.create_engine("mssql+pyodbc:///?odbc_connect=%s" % params)

这也不是数据库权限问题,因为我可以使用与以下相同的连接参数逐行编写:

cursor = conn.cursor()
cursor.execute('insert into test values (1, 'test', 10)')
conn.commit()

我可以写一个循环来逐行插入,但我想知道为什么to_sql 对我不起作用,我担心它不会那么高效。

环境: Python: 2.7 Pandas: 0.20.1 sqlalchemy:1.1.12

提前致谢。

可运行示例

import pandas as pd
from sqlalchemy import create_engine
import urllib

params = urllib.quote_plus("DRIVER={SQL Server Native Client 11.0};SERVER=
<servername>;DATABASE=<databasename>;UID=<username>;PWD=<password>")
engine = create_engine("mssql+pyodbc:///?odbc_connect=%s" % params)

test = pd.DataFrame({'col1':1, 'col2':'test', 'col3':10}, index=[0])
conn=engine.connect().connection
test.to_sql("dbo.test", con=conn, if_exists="append", index=False)

【问题讨论】:

  • 你怎么打电话给to_sql?您是否将 SQLAlchemy 引擎作为 the second argument 传递?
  • 嘿!不,我不是……我只是运行df.to_sql("dbo.test", con=conn, if_exists="append"),pandas 会自动搜索 sqlite_master;我不知道为什么!在哪里conn=engine.connect().connection
  • 如果您可以发布一个简短的可运行示例来演示该问题,那将非常有帮助。这样我们就可以准确地看到一切是如何定义的,并查看哪一行正在生成什么错误消息。
  • @unutbu 查看已编辑问题的可运行示例。谢谢!
  • 最后,我编写了循环逐行上传表格的代码,那里的错误比使用熊猫更清楚。基本上变量类型存在错误...如果我将所有 pandas 数据帧转换为字符串并将其上传到 sql varchar 表,则“pandas.to_sql”可以工作。我已经使用python 2 周了,所以我还不能提供有关格式错误的更多信息。 @unutbu @Scratch'N'Purr 都感谢您的帮助。

标签: python sql python-2.7 pandas dataframe


【解决方案1】:

根据to_sql doccon 参数要么是 SQLAchemy 引擎,要么是旧版 DBAPI2 连接 (sqlite3)。因为您传递的是连接对象而不是 SQLAlchemy 引擎对象作为参数,所以 pandas 推断您传递的是 DBAPI2 连接或 SQLite3 连接,因为它是唯一受支持的连接。要解决此问题,只需执行以下操作:

myeng = sqlalchemy.create_engine("mssql+pyodbc:///?odbc_connect=%s" % params)

# Code to create your df
...

# Now write to DB
df.to_sql('table', myeng, index=False)

【讨论】:

  • 感谢您的回答。事实上,这是我尝试的第一件事,但出现以下错误:AttributeError: 'Engine' object has no attribute 'cursor'。我将不胜感激任何解决方法。
  • 嗯,试试conn = myeng.connect(),然后将其作为连接对象传递?我将myeng 作为参数传递没有任何问题,但后来我使用ODBC Driver 13 for SQL Server 作为我的ODBC 驱动程序,所以它可能是驱动程序之间的细微差别。
  • 相同的结果...我也尝试了engine.raw_connection(),我在另一篇文章中读到了它,我得到了相同的结果。此外,我尝试将驱动程序更改为[SQL Server][ODBC Driver 11 for SQL Server] 也没有运气......
  • 嗯,我不太确定,因为您的语法看起来正确。但我确实找到了一个old post,它有类似的问题,但 SQL 风格不同。那里的 cmets 可能有用。如果一切都失败了,我可能会创建一个干净的环境并在其中安装必要的软件包并再试一次,因为您尝试的应该可以工作。
  • @Scratch'N'Purr 谢谢。我遇到了同样的问题,myeng.connect() 为我工作。
【解决方案2】:

试试这个。 可以连接 MS SQL 服务器(SQL 身份验证)和更新数据

from sqlalchemy import create_engine
params = urllib.parse.quote_plus(
'DRIVER={ODBC Driver 13 for SQL Server};'+
'SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)

engine = create_engine("mssql+pyodbc:///?odbc_connect=%s" % params)

#df: pandas.dataframe; mTableName:table name in MS SQL
#warning: discard old table if exists
df.to_sql(mTableName, con=engine, if_exists='replace', index=False)

【讨论】:

    【解决方案3】:

    所以我遇到了同样的事情。我尝试查看代码,无法弄清楚为什么它不起作用,但看起来它卡在了这个调用上。

    pd.io.sql._is_sqlalchemy_connectable(engine)
    

    我发现如果我先运行它会返回 True,但是一旦我在运行 df.to_sql() 后运行它就会返回 False。现在我在执行df.to_sql() 之前运行它,它确实有效。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-21
      • 2018-05-12
      • 1970-01-01
      • 1970-01-01
      • 2018-05-04
      • 2022-01-09
      • 2015-11-21
      • 1970-01-01
      相关资源
      最近更新 更多