在尝试将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
而不是真正的数据库。
这不是连接问题,因为我可以使用sql-server
从pandas.read_sql
读取相同的连接
已使用
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)
答案 0 :(得分:4)
根据to_sql
doc,con
参数是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)
答案 1 :(得分:1)
所以我遇到了同样的事情。我试着查看代码,无法弄清楚为什么它不起作用但看起来它会卡在这个调用上。
pd.io.sql._is_sqlalchemy_connectable(engine)
我发现如果我先运行它会返回True,但是在运行df.to_sql()之后运行它会立即返回False。现在我在执行df.to_sql()之前运行它,它确实有效。
希望这会有所帮助。
答案 2 :(得分:0)
试试这个。 很好地连接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)