web-dev-qa-db-ja.com

MySQLdbが実行する実際のクエリを出力しますか?

実行されたクエリをデバッグする方法を探していますが、パラメータの挿入が完了した後、MySQLdbが実行する実際のクエリを出力する方法があるのだろうかと思っていましたか?ドキュメントから、最後のクエリ実行に関する情報を提供するCursor.info()呼び出しがあるはずのように見えますが、これは私のバージョン(1.2.2)には存在しません。

これは明らかな質問のように思えますが、すべての検索で答えを見つけることができませんでした。前もって感謝します。

64
xitrium

例外が発生した場合でも実行する最後のクエリ文字列を保持するcursor._last_executedというカーソルオブジェクトの属性が見つかりました。これは、プロファイリングやMySQLクエリロギングの両方がパフォーマンスに影響を及ぼし、より多くのコードまたはより多くの個別のログファイルなどを必要とするため、本番環境での方が簡単で優れていました。

自分の質問に答えるのは嫌いですが、これは私たちにとってはうまく機能しています。

114
xitrium

カーソル属性_last_executedを使用して、最後に実行されたクエリを印刷できます。

try:
    cursor.execute(sql, (arg1, arg2))
    connection.commit()
except:
    print(cursor._last_executed)
    raise

現在、これをpymysqlの実際の機能として取得する方法についての議論があります( pymysql issue#330:mogrifyをカーソルに追加し、実行する正確な文字列を返します ; pymysqlMySQLdbの代わりに使用する必要があります)

編集:私は今までそれをテストしませんでしたが、 this commit は次のコードが機能する可能性があることを示します。

cursor.mogrify(sql, (arg1, arg2))
27
Martin Thoma

私のために/今のところ_last_executedはもう機能しません。アクセスしたい現在のバージョン

cursor.statement

参照: https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-statement.html

15
martn_st

それを行う1つの方法は、 プロファイリング をオンにすることです。

cursor.execute('set profiling = 1')
try:
    cursor.execute('SELECT * FROM blah where foo = %s',[11])
except Exception:
    cursor.execute('show profiles')
    for row in cursor:
        print(row)        
cursor.execute('set profiling = 0')

利回り

(1L, 0.000154, 'SELECT * FROM blah where foo = 11')

引数がクエリに挿入され、クエリが失敗してもクエリがログに記録されたことに注意してください。

別の方法は、ロギングをオンにしてサーバーを起動することです:

Sudo invoke-rc.d mysql stop
Sudo mysqld --log=/tmp/myquery.log

次に、/ tmp/myquery.logを調べて、サーバーが受信したものを調べる必要があります。

5
unutbu
4
picmate 涅

私は_cursor._last_executed_で一般的には運が良かったのですが、cursor.executemany()と一緒に使用すると正しく動作しません。これは、最後のステートメントを除くすべてを削除します。基本的には、代わりにそのインスタンスで現在使用しているものです(実際のMySQLDbカーソルソースからの調整に基づいています)。

_def toSqlResolvedList( cursor, sql, dynamicValues ):
    sqlList=[]
    try:
        db = cursor._get_db()
        if isinstance( sql, unicode ): 
            sql = sql.encode( db.character_set_name() )
        for values in dynamicValues :
            sqlList.append( sql % db.literal( values ) )
    except: pass
    return sqlList    
_
2
BuvinJ