MySQLデータベースの行の更新に問題があります。これが私が実行しようとしているコードです:
import MySQLdb
conn=MySQLdb.connect(Host="localhost", user="root", passwd="pass", db="dbname")
cursor=conn.cursor()
cursor.execute("UPDATE compinfo SET Co_num=4 WHERE ID=100")
cursor.execute("SELECT Co_num FROM compinfo WHERE ID=100")
results = cursor.fetchall()
for row in results:
print row[0]
print "Number of rows updated: %d" % cursor.rowcount
cursor.close()
conn.close()
このプログラムを実行すると、次のような出力が得られます。
4
更新された行数:1
動作しているようですが、MySQLコマンドラインインターフェース(CLI)からデータベースにクエリを実行すると、データベースがまったく更新されていないことがわかります。ただし、CLIからUPDATE compinfo SET Co_num=4 WHERE ID=100;
と入力すると、データベースは期待どおりに更新されます。
私の問題は何ですか? WindowsボックスでMySQL 5.1.30を使用してPython 2.5.2を実行しています。
確かではありませんが、INNODBテーブルを使用していて、コミットを行っていないと思います。 MySQLdbはトランザクションを自動的に有効化すると思います。
close
を呼び出す前にconn.commit()
を呼び出します。
MySQLdbのデフォルトでは自動コミットがオフになっているため、最初は混乱する可能性があります。接続は独自のトランザクションに存在し、そのトランザクションをコミットするまで、他の接続から行った変更を確認することはできません。
他の人が指摘したように、updateステートメントの後にconn.commit()
を実行するか、接続オブジェクトを作成した直後にconn.autocommit(True)
を設定してこの機能を完全に無効にすることができます。
変更を手動でコミットするか、自動コミットをオンにする必要があります。
SELECTが変更された(ただし永続化されていない)データを返す理由は、接続がまだ同じトランザクション内にあるためです。
Pythonのコネクタが自動コミットを自動的にオフにすることがわかりました。この動作を変更する方法はないようです。もちろん、オンに戻すこともできますが、クエリログを見ると、接続後に2つの無意味なクエリを実行して、自動コミットをオフにしてから再度オンにします。