web-dev-qa-db-ja.com

python mysqldbを使用して一度に多くの行を挿入する方法

リストのリストがあります(例:[['a','b'],['c','d']])。

Tというテーブルと2つのフィールドF1F2があります。フィールドリストの最初の項目はF1にマップされ、2番目の項目はF2にマップされます。

このようなforループを使用するのではなく、単一のコマンドまたは呼び出しで各内部リストの行を挿入するにはどうすればよいですか?

for i in [['a','b'],['c','d']]:
    c.execute("insert into T (F1,F2) values (%s, %s)", (i[0], i[1]))
32
Tampa

MySQLdbユーザーズガイド から:

c.executemany(
      """INSERT INTO breakfast (name, spam, eggs, sausage, price)
      VALUES (%s, %s, %s, %s, %s)""",
      [
      ("Spam and Sausage Lover's Plate", 5, 1, 8, 7.95 ),
      ("Not So Much Spam Plate", 3, 2, 0, 3.95 ),
      ("Don't Wany ANY SPAM! Plate", 0, 4, 3, 5.95 )
      ] )

あなたの場合:

c.executemany("insert into T (F1,F2) values (%s, %s)",
    [('a','b'),('c','d')])
62
zenpoy

@adamhajariのような1つのステートメントにすべての行を挿入し、@ zenpoyのようなSQLインジェクションを同時に回避することができます。大きな挿入ステートメントを作成し、mysqldbのexecuteにフォーマットを行わせるだけです。

values_to_insert = [('a','b'),('c','d')]
query = "INSERT INTO T (F1, F2) VALUES " + ",".join("(%s, %s)" for _ in values_to_insert)
flattened_values = [item for sublist in values_to_insert for item in sublist]
c.execute(query, flattened_values)

非常に読みやすいものではありませんが、executemanyよりも若干高速です(ローカルDBに50000行のバッチを挿入しようとしましたが、executemanyは20%遅くなりました)。

19
Rems