web-dev-qa-db-ja.com

to_sql pandas SQL server into SQL server error:DatabaseError

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] Invalid object name '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)

次のように同じ接続パラメーターを使用して1行ずつ書き込むことができるので、データベース権限の問題でもありません。

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

1行ずつinstertにループを書き込むこともできますが、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)
5
AlexSB

による - 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)
6
Scratch'N'Purr

これを試して。 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)
1
CaiYongAn

だから私はこれと同じことに遭遇しました。コードを調べてみましたが、なぜ機能しないのかわかりませんでしたが、この呼び出しでスタックしているようです。

pd.io.sql._is_sqlalchemy_connectable(engine)

これを最初に実行するとTrueを返しますが、df.to_sql()を実行した後で実行するとすぐにFalseを返します。現在、私はdf.to_sql()を実行する前にそれを実行しており、実際に機能します。

お役に立てれば。

1
Faller