Imprimir la consulta real MySQLdb se ejecuta?


Estoy buscando una manera de depurar consultas a medida que se ejecutan y me preguntaba si hay una manera de tener MySQLdb imprimir la consulta real que se ejecuta, después de que haya terminado de insertar los parámetros y todo eso? De la documentación, parece como si se supone que hay un Cursor.info () llamada que dará información sobre la última ejecución de la consulta, pero esto no existe en mi versión (1.2.2).

Esta parece una pregunta obvia, pero durante toda mi búsqueda no he estado capaz de encontrar la respuesta. Gracias de antemano.

Author: xitrium, 2011-08-16

8 answers

Encontramos un atributo en el objeto cursor llamado cursor._last_executed que contiene la última cadena de consulta para ejecutarse incluso cuando se produce una excepción. Esto fue más fácil y mejor para nosotros en la producción que usar el perfilado todo el tiempo o el registro de consultas MySQL, ya que ambos tienen un impacto en el rendimiento e implican más código o más correlaciones de archivos de registro separados, etc.

Odio responder a mi propia pregunta, pero esto está funcionando mejor para nosotros.

 101
Author: xitrium,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-24 14:16:57

Puede imprimir la última consulta ejecutada con el atributo cursor _last_executed:

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

Actualmente, hay una discusión sobre cómo obtener esto como una característica real en pymysql (ver pymysql issue # 330: Add mogrify to Cursor, que devuelve la cadena exacta a ejecutar; pymysql debe utilizarse en lugar de MySQLdb)

Editar: No lo he probado por ahora, pero este commit indica que el siguiente código podría funcionar:

cursor.mogrify(sql, (arg1, arg2))
 22
Author: Martin Thoma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-13 18:04:59

Para mí / por ahora _last_executed ya no funciona. En la versión actual desea acceder a

cursor.statement.

Véase: https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-statement.html

 10
Author: martn_st,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-17 20:33:52

Una forma de hacerlo es activar la creación de perfiles :

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')

Rinde

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

Observe que los argumentos se insertaron en la consulta, y que la consulta se registró a pesar de que la consulta falló.

Otra forma es iniciar el servidor con el registro activado:

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

Entonces usted tiene que tamizar a través de /tmp/myquery.inicie sesión para averiguar lo que recibió el servidor.

 4
Author: unutbu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-15 22:24:08
 1
Author: picmate 涅,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-17 21:50:30

He tenido suerte con cursor._last_executed generalmente hablando, pero no funciona correctamente cuando se utiliza con cursor.executemany(). Eso deja todo menos la última declaración. Esto es básicamente lo que uso ahora en esa instancia en su lugar (basado en ajustes de la fuente real del cursor 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    
 1
Author: BuvinJ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-02 20:02:22

No puedo decir que haya visto

Cursor.info()

En la documentación, y no puedo encontrarlo después de unos minutos de búsqueda. ¿Tal vez viste alguna documentación vieja?

Mientras tanto, siempre puede activar MySQL Query Logging y echar un vistazo a los archivos de registro del servidor.

 0
Author: Nick Craig-Wood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-08-15 22:12:08

Asume que tu sql es como 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))
 -1
Author: 郭润民,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-09 01:35:30