データフレームをSQLServerテーブルに書き込もうとしています。私のコード:
conn = pymssql.connect(Host="Dev02", database="DEVDb")
cur = conn.cursor()
query = "INSERT INTO dbo.SCORE_TABLE VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
cur.executemany(query, df_sql)
conn.commit()
cur.close()
conn.close()
df_sql
のディメンションは(5860, 20)
です。つまり、データフレームの列数は、SQLServerテーブルの列数と同じです。それでも次のエラーが発生します:
ValueError:使用可能なパラメータよりもSQLのプレースホルダーが多い
以下に更新
コメントの1つに従って、以下のようにturbodbc
を使用してみました。
conn = turbodbc.connect(driver="{SQL Server}", server="Dev02", Database="DEVDb")
conn.use_async_io = True
cur = conn.cursor()
query = "INSERT INTO dbo.STG_CONTACTABILITY_SCORE VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"
cur.executemany(query, df_sql.values)
cur.commit()
cur.close()
conn.close()
次のエラーが発生します:
ValueError:複数の要素を持つ配列の真理値があいまいです。 a.any()またはa.all()を使用します
わかりません。ここで何が問題なのですか。 df_sql.values
が表示されますが、何も問題はありません。
Ndarrayの最初の行は次のとおりです。
[nan 'DUSTIN HOPKINS' 'SOUTHEAST MISSOURI STATE UNIVERSITY' 13.0
'5736512217' None None 'Monday' '8:00AM' '9:00AM' 'Summer' None None None
None '2017-12-22 10:39:30.626331' 'Completed' None '1-11KUFFZ'
'Central Time Zone']
各列名を指定する必要があると思います。データフレームインデックスを課金するには、テーブルにidフィールドが必要であることを忘れないでください。
conn = pymssql.connect(Host="Dev02", database="DEVDb")
cur = conn.cursor()
query = """INSERT INTO dbo.SCORE_TABLE(index, column1, column2, ..., column20)
VALUES (?, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
%s, %s, %s, %s, %s, %s)"""
cur.executemany(query, df_sql)
conn.commit()
cur.close()
conn.close()
さて、私はpandasを使用していて、最後のデータフレームを次のようにcsvにエクスポートしました:
df.to_csv('new_file_name.csv', sep=',', encoding='utf-8')
次に、pyobdc
とBULK INSERT
Transact-SQLを次のように使用しました。
import pyodbc
conn = pyodbc.connect(DRIVER='{SQL Server}', Server='server_name', Database='Database_name', trusted_connection='yes')
cur = conn.cursor()
cur.execute("""BULK INSERT table_name
FROM 'C:\\Users\\folders path\\new_file_name.csv'
WITH
(
CODEPAGE = 'ACP',
FIRSTROW = 2,
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n'
)""")
conn.commit()
cur.close()
conn.close()
SQLServerに15314行を課金するのは1秒でした。これがあなたにアイデアを与えることを願っています。
私が正しく理解している場合は、使用したい DataFrame.to_sql() メソッド:
df_sql.to_sql('dbo.SCORE_TABLE', conn, index=False, if_exists='append')
値の間にコンマ区切り文字がないため、executemany
はdf.values
呼び出しからのndarray
の各行をoneアイテムとして扱う可能性があります。したがって、プレースホルダーは実際のバインドされた値よりも多く、不一致エラーが発生します。
配列をタプルのタプル(またはリストのリスト/リストのタプル/タプルのリスト)に変換してから、そのオブジェクトをexecutemany
に渡すことを検討してください。
query = "INTO dbo.SCORE_TABLE VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"
sql_data = Tuple(map(Tuple, df.values))
cur.executemany(query, sql_data)
cur.commit()