« ^ »

PyMySQLでバルクINSERTする

所要時間: 約 1分

MySQLでバルクINSERTしたい場合 cursor.executemany() を使う。

テスト用のテーブルを作成する。

show create table foo;
+-------+-----------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                    |
+-------+-----------------------------------------------------------------------------------------------------------------+
| foo   | CREATE TABLE `foo` (
  `id` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci |
+-------+-----------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

cursor.executemany() を呼び出すコードを実装する。

main.py

import pymysql
from pymysql.cursors import DictCursor

MYSQL_HOST = "localhost"
MYSQL_PORT = 3306
MYSQL_USER = ""
MYSQL_PASSWORD = ""
MYSQL_DATABASE = "testing"

mysql_conn = pymysql.connect(
    host=MYSQL_HOST,
    port=MYSQL_PORT,
    user=MYSQL_USER,
    password=MYSQL_PASSWORD,
    db=MYSQL_DATABASE,
    charset="utf8mb4",
    use_unicode="true",
    cursorclass=DictCursor,
)

try:
    with mysql_conn.cursor() as cursor:
        res = cursor.executemany(
            """
            INSERT INTO foo (
             id
            ) VALUES (%s)
            """,
            [
                [1],
                [2],
                [3],
                [4],
            ]
    
        )
        mysql_conn.commit()
finally:
    mysql_conn.close()

コードを実行する。

python main.py

結果を確認する。

mysql> SELECT * FROM foo;
SELECT * FROM foo;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
+------+
4 rows in set (0.00 sec)

INSERTされている。general_logを見ると以下のクエリが発行されている事が分かる。

Connect   [email protected] on testing using TCP/IP
Query     SET NAMES utf8mb4
Query     SET AUTOCOMMIT = 0
Query     INSERT INTO foo (
             id
            ) VALUES (1),(2),(3),(4)
Query     COMMIT
Quit

期待した通りの挙動をしている事が分かる。