打印实际查询MySQLdb运行?


73

我正在寻找一种在执行查询时调试查询的方法,我想知道是否有一种方法可以让MySQLdb在完成参数插入及所有操作之后打印出它运行的实际查询?从文档看来,似乎应该有一个Cursor.info()调用,该调用将提供有关上次查询运行的信息,但是在我的版本(1.2.2)中不存在。

这似乎是一个显而易见的问题,但是对于我所有的搜索,我一直找不到答案。提前致谢。


不知道该库,但是如果它使用实际的MySQL预准备语句,则实际查询将类似于EXECUTE stmt USING @var1, var2,....。不确定是否对您有帮助。
Mchl 2011年

我只是打开常规查询日志,然后查看执行了什么查询。
Michael Mior

@MichaelMior并非总是这样,特别是对于托管MySQL(例如Amazon的RDS)而言。python侧访问它很有用。(只想指出,改变mysql日志设置并不总是可行的。)
Travis Leleu 2014年

@TravisLeleu我敢肯定,在某些情况下,这是对的,但是您可以访问RDS上的常规日志。docs.aws.amazon.com/AmazonRDS/latest/UserGuide/…–
Michael

Answers:


119

我们在游标对象上发现了一个名为的属性,cursor._last_executed即使发生异常,该属性 也保留要运行的最后一个查询字符串。与一直使用概要分析或MySQL查询日志记录相比,这对我们在生产中更容易和更好,因为这两者都对性能产生影响,并且涉及更多代码或与更多相关的独立日志文件等。

讨厌回答我自己的问题,但这对我们来说更好。


36

您可以使用cursor属性打印最后执行的查询_last_executed

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

当前,正在讨论如何将其作为pymysql中的真实功能使用(请参阅pymysql问题#330:向游标添加mogrify,该游标将返回要执行的确切字符串pymysql应使用而不是MySQLdb

编辑:我现在尚未对其进行测试,但是此提交指示以下代码可能有效:

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

pymysql现在支持cur.mogrify(qstr,qargs)
e1i45 '16



6

一种方法是打开分析

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以找出服务器收到的内容。


2

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

假设你的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))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.