2011-01-16 7 views
15

コードに続いて、Pythonの2.6.6と1.2.2のMySQLdbを使用すると、同期していコマンドが発生します。あなたは今 MySQLdbは例外をこのコマンドを実行することはできません。方法「同期のうちコマンドを、あなたは今、このコマンドを実行することはできません」(2014年)例外

import MySQLdb 

conn = MySQLdb.connect(db="test", user="root") 
cursor = conn.cursor(MySQLdb.cursors.DictCursor) 

cursor.execute("BEGIN; CREATE TABLE t1 (t1_id INT PRIMARY KEY AUTO_INCREMENT); COMMIT;") 
cursor.execute("BEGIN; CREATE TABLE t2 (t2_id INT PRIMARY KEY AUTO_INCREMENT); COMMIT;") 

例外が2番目のクエリの実行中に発生します。私が読んだように、例外は一般にMySQLのC API実装の制限によって引き起こされます。これは、並行クエリの実行を許可しません。私は上記の2つのクエリの間にカーソルオブジェクトを再作成する場合は

は、問題が回避されるが、生憎ソリューションは、私には完璧なようではありません。私はデータベース接続とクエリの実行に非常に単純な制限があり、現在のトランザクションをコミットする(潜在的には他の副作用がある)ので、各クエリの実行後にカーソルを再作成しない方が望ましいです。

したがって、私の質問は:この例外を回避するための他の方法は何ですか?どのように次のクエリの実行のためのカーソルオブジェクトを準備する?たぶん、他のデータベースインターフェイスを使用しているときに比較的中立的で、MySQLdbの場合に問題を回避するPython DB APIによって期待されるいくつかのメソッドがありますか?お時間を事前に

おかげで、助け:)

編集:私は質問を投稿した後、私は私が(カーソル破壊の副作用について読むためにはPython DBのAPI仕様を読み始めた トランザクションが:)もうコミットので、確認してください)と私の周り以下、代替の仕事が見つかりません:

cursor.execute("BEGIN; CREATE TABLE t1 (t1_id INT PRIMARY KEY AUTO_INCREMENT); COMMIT;") 
while cursor.nextset() is not None: pass 
cursor.execute("BEGIN; CREATE TABLE t2 (t2_id INT PRIMARY KEY AUTO_INCREMENT); 

問題は、私はそれが何をするのか分からないということである(それは1 2回を返し、その後None) 。私はこの方向に掘り下げるべきでしょうか?私の問題の解決策を見つけるために、これらのセットの概念を理解する必要がありますか?

答えて

9

DB-APIはそう、最初のコマンドでトランザクションを開始し、それをコミットするために、独自のAPI呼び出しを持つ、独自にトランザクションを処理しようとします:

cursor.execute("CREATE TABLE t1 (t1_id INT PRIMARY KEY AUTO_INCREMENT)") 
cursor.commit() 
cursor.execute("CREATE TABLE t2 (t2_id INT PRIMARY KEY AUTO_INCREMENT)") 
cursor.commit() 

私の意見では、これは、深刻ですPythonのDB-APIの目立たない設計上の誤りで、トランザクション外でコマンドを実行したり、トランザクションを適切に制御することを重大な面倒にしています。 SQLiteのBEGIN EXCLUSIVE TRANSACTIONのようなものを使用する。それは...ない実際のデータベースの経験を持つ誰かがAPIを設計するために許可されたかのよう

+6

+1だ、またはあなただけのデフォルトでは無効である最初の場所でtrueに__autocommit__設定することができます。この 'cursor.connection.autocommit(True)'のように。 – mouad

+0

@singularity:そうした場合、低レベルでAPIの動作を変更しています。たとえば、接続をサードパーティのコードに渡すと、あなたが噛む可能性があります。 –

+0

@Glennメイナード:いいえ、それは私たちが本当の時間の節約ではなく、毎回やって欲しいとき、それはちょうど、いくつかのケースで非常に役立ちます自動コミットを有効に、我々は我々のコード:)で作成したカーソルの接続のための__autocommit__オプションを有効にします、ではありません'cursor.commit()' ... – mouad

関連する問題