2011-08-15 35 views
48

我正在尋找一種方式來調試查詢,因爲他們正在執行,我想知道是否有辦法讓MySQLdb打印出它運行的實際查詢,它已經完成插入參數和所有這些後?從文檔中,似乎應該有一個Cursor.info()調用,它會提供有關最後一次查詢運行的信息,但這在我的版本(1.2.2)中不存在。打印MySQLdb運行的實際查詢?

這似乎是一個明顯的問題,但對於我所有的搜索,我一直無法找到答案。提前致謝。

+0

不知道這個庫,但如果它使用實際MySQL的預處理語句,則實際查詢將如下像'EXECUTE stmt USING @ var1,var2,....'。不確定它是否對你有幫助。 – Mchl

+0

我只打開[通用查詢日誌](http://dev.mysql.com/doc/refman/5.1/en/query-log.html),然後查看執行了哪個查詢。 –

+0

@MichaelMior這並不總是一種選擇,尤其是像託管MySQL這樣的亞馬遜RDS。讓python端訪問它是很有用的。 (只是想指出,轉變mysql日誌設置並不總是可行)。 –

回答

85

我們發現光標對象上的屬性,叫做cursor._last_executed包含最後查詢字符串,即使在發生異常時運行。對於我們來說,生產中比使用性能分析或MySQL查詢記錄更容易和更好,因爲這兩者都會對性能造成影響,並涉及更多代碼或更多關聯單獨的日誌文件等。

討厭回答我自己的問題但是這對我們來說效果更好。

+0

謝謝你在這個xitrium上刷新我:) – fedmich

0

我不能說我見過

Cursor.info() 

在文檔,幾分鐘後搜索,我不能找到它。也許你看過一些舊的文檔?

在平均時間,你可以隨時打開MySQL Query Logging和看看服務器的日誌文件。

+0

我在這裏看到http://mysql-python.sourceforge.net/MySQLdb.html的「光標對象」 :「info() 返回關於最後一個查詢的一些信息,通常你不需要檢查它。」 – xitrium

3

一種方式來做到這一點是開啓profiling

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進行篩選,找出收到什麼樣的服務器。

18

您可以用光標屬性_last_executed打印最後執行的查詢:

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

目前,有一個討論如何讓本作中pymysql一個真正的功能(參見pymysql issue #330: Add mogrify to Cursor, which returns the exact string to be executed; pymysql應,而不是使用MySQLdb

編輯:我沒有現在測試,但this commit表明,下面的代碼可能工作:

cursor.mogrify(sql, (arg1, arg2)) 
+0

pymysql現在支持cur.mogrify(qstr,qargs) – e1i45

0

假設你的SQL就像select * from table1 where 'name' = %s

from _mysql import escape 
from MySQLdb.converters import conversions 

actual_query = sql % tuple((escape(item, conversions) for item in parameters)) 
0

我有運氣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