Python で MySQLのテーブルに INSERT しても反映されない(丸2日無駄に!!)

Python プログラムからの MySQL 操作 で Insertが反映されない!!

後学のために記しておきます。

はい、私はにわかPython使いです。他の言語も扱うのでPython命でもありません。

今回丸々2日間ハマってしまいました。

MySQLでなぜか Insert だけ反映されない!!

こういうプログラムでした。
CSVファイルを読み込んでMySQLのデータベースのテーブルに格納します。
難しいことはありません。
MySQLのライブラリは python-MySQL 。
プログラム冒頭で元となるテンプレートテーブルをコピーしてテーブルを作成します。

import MySQLdb

conn = MySQLdb.connect(host="extdbsrv", db="test", user="user", passwd="xxx", charset="utf8")

cursor = conn.cursor()
sql = "CREATE TABLE test like table_template"
cursor.execute(sql)

テンプレートテーブルはphpMyAdminで作成します。
プログラムで生成しないのは、コメント付のテーブルを作成するのにphpMyAdminが便利だからです。

プログラムを実行します。正常にテーブルがコピーされます。
もちろんこの後にもプログラムが続きます。
CSVファイルをオープンして1行ずつ読み込み、テーブルにInsertしていきます。
カラムが50個もあり、SQLで書き込む処理が大変です。

なぜかデータベースにデータの書き込みがされない!!

プログラムエラーは出なくなりましたが、なぜかデータベースに反映されず書き込まれません。
もちろんSQLエラー(MySQLが吐くエラー)も出てないようです。
先にテーブルコピーはできているので、DBに接続できてますし、書き込み権限はあるはずです。

sql = "INSERT INTO hwdata01 ( id , prefectural_id ) values (NULL,1)"
cursor.execute(sql)

プライマリーキーだけinsertするプログラムにしましたが、レコードは追加されず。。。

トラブルシューティング

プログラムを眺めていてもどうにも原因がわかりませんが、あわてずトラブルシューティングです。

  • ローカル(Windows)環境で作成していましたが、Linuxサーバー上でも同じPythonプログラムを実行 => ダメ
  • DB接続アカウントに全権限を与えた => ダメ
  • 接続書き込み先のサーバーを変えてみてテスト => ダメ
  • CSV読み込みはやめて仮データをInsertするだけのプログラムに変更 => ダメ
  • phpMyAdminから同じSQL文を実行 => 書き込みされる
  • MySQLのCLIクライアントから同じSQL文を実行 => 書き込みされる

結局はPythonからの書き込みだけInsertが反映されません。

不思議な現象! autoincrement はカウントされている

CLIクライアント(MySQLコマンドライン)からinsertやselectをしていて気づきましたが、autoincrement(自動連番)は機能しているようです。
pythonプログラムでinsertすると、レコードは挿入されませんが、ちゃんとidが1増えているのです。

Image1.jpg

phpMyAdminの画面ですが、id が飛び飛びになっています。
このidが書き込みされているのは、CLIクライアントから操作した場合です。

ますますわからなくなりました。

そうかコミットされてないんじゃないか

色々検索をしている途中に、コミットされてないんじゃないかという疑念がわきました。
Python以外は気にしなくていいんですが(良くないですが)、他の言語は自動的にファイルクローズやDBコミットを自動的にやってくれていることが多いので、極端に気にしなくてもだいたい何とかなります。

気にしなかったわけではないのですが、ファイルのオープンも復数していたので目に付きませんでした。

commit/close 文をプログラムの最後に付け加えます。

cursor.close
conn.commit
conn.close

これで何とかと願いながら実行しますが、特に挙動は変わらず。。。

もしやと思い

ここまで2日間費やし、記載していないことでもできることは色々やりました。

もしやと思い、命令文の後ろに括弧(カッコ)を付け加えます。

cursor.close()
conn.commit()
conn.close()

結果は・・・思ったようにInsertされました。

何だったんでしょうか。カッコをつけるつけないはあまり気にしませんでした。
というより、つけなければエラーか警告を吐いてくれればいいのに。

Python使いの方々は with 文を使って自動的にコミットさせろとか言うんでしょうけど。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.