web-dev-qa-db-ja.com

pymssqlを使用してSQLServerテーブルにデータを挿入します

データフレームを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']
4

各列名を指定する必要があると思います。データフレームインデックスを課金するには、テーブルに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')

次に、pyobdcBULK INSERTTransact-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秒でした。これがあなたにアイデアを与えることを願っています。

2
virtualdvid

私が正しく理解している場合は、使用したい DataFrame.to_sql() メソッド:

df_sql.to_sql('dbo.SCORE_TABLE', conn, index=False, if_exists='append')
0
MaxU

値の間にコンマ区切り文字がないため、executemanydf.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()
0
Parfait