Edited at

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

More than 1 year has passed since last update.


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