8

私はMySQLデータベースと相互作用するPythonでプログラムを書いています。SQLクエリにはMySQLdbを使用します。問題はNoneを返すことですが、データベースブラウザを使用すると、その行が存在するfetchone()ことがわかります。このコード:

query = "SELECT * FROM revision WHERE rev_id=%s;" 
cursor.execute(query % revision_id)
row = cursor.fetchone()
if row == None:
    raise Exception("there isn't revision with id %s" % revision_id)

ここで何が起こっているのかわかりません。何か案は?

編集:わかりました、場合によっては機能する場合もありますが、機能しない場合でも、行はテーブルに存在します。カーソルオブジェクトを関数に渡していますが、上記のコードは関数内にあります。問題はこのカーソルオブジェクトに関連しています。問題は、関数への引数としてカーソルを渡すことでしょうか?どうすればテストできますか?

EDIT2:はい、問題は、カーソルを数回使用した後、カーソルが機能しないことです。他のプログラムがDBに接続しているのか、私が何か間違ったことをしているのか。DBから情報を取得する関数をwhile呼び出すループがあります。何度か繰り返した後、それは再び機能しません。whileループが機能している間にDBに書き込む別のプログラムがあります。

4

3 に答える 3

5

さて、db.autocommit(True)私の問題を解決しました。

于 2012-08-06T04:32:54.933 に答える
3

これは、MySQLサーバーのトランザクション分離レベルに関連しています。InnoDbのデフォルトレベルの場合REPEATABLE_READ、最初の読み取り時にスナップショットが作成され、同じカーソルによる後続の読み取りがこのスナップショットから作成されます。分離レベルの詳細については、こちらをご覧ください

同じカーソルを再利用して複数のクエリを実行するときに通常必要なのは、ですREAD_COMMITTED。ありがたいことに、SQLサーバーでこれを変更できない場合は、カーソルを特定の分離レベルに設定できます。

cur = conn.cursor()
cur.execute("SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED")

これにより、作成するすべてのクエリで、最新のコミット済みスナップショットが使用されるようになります。

于 2019-09-04T16:24:27.630 に答える
0

ベストプラクティスは、すべてのクエリが実行された後、dbをコミットすることです db.commit()

于 2018-12-05T09:56:05.920 に答える