4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MySQLdbでレコードを保存できない対処法(autocommitを使う)

Last updated at Posted at 2019-09-01

MySQLdb.connectの引数全解説はMySQLdb.connectの引数全解説もぜひお願いします!

また,結論だけ見たい方はautocommitを使うの章へどうぞ.
本ページの目的は,いっぱいINSERTしたいときとかUPDATEしたいときとかです.try-except使ってINSERTに失敗したときの処理とかは書いていません.

Insertができないときの普通の対処法

Pythonを使ってMySQLを操作する際にSELECT文はうまくいくのにINSERT文がうまくいかない,ということの説明をしているサイトはいくつもあると思います.この原因はcommitをしていないからで,Qiitaを始めとして,commitをいちいち書く方法や,PythonらしくWith文を使えるようにしよう!というものが色々見つかります.

(参考)
Python で MySQLのテーブルに INSERT しても反映されない(丸2日無駄に!!)
MySQLdbの優雅な使い方
PythonでMySQLのデータ操作をやろう

最後のページの筆者の方はautocommit反対派のようですが….

簡単にMySQLdbの使い方

一般的にはこのように使います.

basic.py
import MySQLdb

# データベースに接続
con = MySQLdb.connect(
        user='MySQLのユーザー名',
        password='MySQLのパスワード',
        host='MySQLのホスト名',
        database='データベースの名前',
    )

# カーソルの生成
cur = con.cursor()

# SQL文を作る
# 入力したい数だけ%sは必要
# テーブルの全てのカラムに値を入れる(NULLがなかったりデフォルト値を使わなかったり)なら `(カラム名1, カラム名2, ...)` は不要
sql = "INSERT into テーブル名 (カラム名1, カラム名2, ...) values (%s, %s, ...)"
# 実際の値はここに書く.タプルを書くとき,1つしか中身がないときもカンマが必要なことに注意
cur.execute(sql, (カラム1の値, カラム2の値, ...))
# 保存するためにはコミットが必要
con.commit()
# 必要なだけこのブロックを繰り返す

# 終わるとき
cur.close()
con.close()

MySQLdb.connect()関数の引数の説明はMySQLdb.connectの引数全解説を参考にしてください.

Commit忘れがだるい,そもそもコードが煩雑になる

みんなが抱えている煩わしさのようです.これを回避するために,With文を使う方法がよく取り上げられています.けど個人的に,毎回connectからやるのよくないと思うんですよね.(それが良いのだとしたら2回もcloseしないはず)

autocommitを使う

ここでGitHubのソースをちゃんと見てみましょう.
(GitHub)https://github.com/PyMySQL/mysqlclient-python/blob/master/MySQLdb/connections.py
(日本語訳)MySQLdb.connectの引数全解説

MySQLdb.connectという関数には引数があり,userやpassword,hostやdatabaseは書くことが多いと思います.他にもcharsetなどは少なくとも使うでしょうか(日本語の場合はutf8utf8mb4ですよねきっと).
これ以外にも,autocommitという引数があります.というわけで,以下が本ページの最後のコードです.

advance.py
import MySQLdb

# データベースに接続
con = MySQLdb.connect(
        user='MySQLのユーザー名',
        password='MySQLのパスワード',
        host='MySQLのホスト名',
        database='データベースの名前',
        autocommit=True, # ポイント
    )

# カーソルの生成
cur = con.cursor()

# クエリの実行
sql = "INSERT into テーブル名 (カラム名1, カラム名2, ...) values (%s, %s, ...)"
cur.execute(sql, (カラム1の値, カラム2の値, ...))
# これで保存されている(コミット済み)なので,con.commit()は不要
# 必要なだけこのブロックを繰り返す

# 終わるとき
cur.close()
con.close()

commit関数がいらないのでいいですね.connectも一回ですし,with文使うよりも個人的にはスマートです.いっぱいINSERTとかUPDATEしたいときは便利です.

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?