MightyCraft

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 文を使って自動的にコミットさせろとか言うんでしょうけど。