2010-07-24 24 views
7

Hay muchas funciones de escape en el módulo de Python mysqldb cuya documentación no entiendo, y mis esfuerzos por buscarlas no han revelado nada.Documentación oculta de Python mysqldb

>>> print _mysql.escape.__doc__ 
escape(obj, dict) -- escape any special characters in object obj 
using mapping dict to provide quoting functions for each type. 
Returns a SQL literal string. 

This documentation page dice lo mismo. ¿Pero qué se supone que es en ese "dict mapping"? Intenté un par de cosas (en su mayoría al azar) y solo recupero los errores. Lo que es aún más frustrante es que, mientras que el método funciona escape_string(), su cadena de documentación es:

>>> print _mysql.escape_string.__doc__ 
escape_string(s) -- quote any SQL-interpreted characters in string s. 

Use connection.escape_string(s), if you use it at all. 
_mysql.escape_string(s) cannot handle character sets. You are 
probably better off using connection.escape(o) instead, since 
it will escape entire sequences as well as strings. 

lo tanto, estoy mejor de usar _mysql.escape(), ¿verdad? Bueno, eh ... está bien, pero ¿cómo? ¿Qué demonios es ese "dict mapping"? PHP, al menos de esa manera, era mucho menos críptico.

Respuesta

7

Lo aprendí buscando en /usr/lib/pymodules/python2.6/MySQLdb/connections.py para ver cómo se llamaba connection.escape. Un poco de olfateo conduce a MySQLdb.converters.conversions. Aquí hay un fragmento:

{0: <class 'decimal.Decimal'>, 
1: <type 'int'>, 
... 
<type 'dict'>: <built-in function escape_dict>, 
<type 'NoneType'>: <function None2NULL at 0xae9717c>, 
<type 'set'>: <function Set2Str at 0xae9709c>, 
<type 'str'>: <function Thing2Literal at 0xae971b4>, 
<type 'tuple'>: <built-in function escape_sequence>, 
<type 'object'>: <function Instance2Str at 0xae971ec>, 
<type 'unicode'>: <function Unicode2Str at 0xae9710c>, 
<type 'array.array'>: <function array2Str at 0xae9725c>, 
<type 'bool'>: <function Bool2Str at 0xae97294>} 

Usted puede utilizar de esta manera:

import MySQLdb 
import MySQLdb.converters 
import datetime 

now=datetime.datetime.now() 
connection=MySQLdb.connect(
    host=HOST,user=USER,passwd=PASS,db=MYDB) 
print(connection.escape((1,2,now),MySQLdb.converters.conversions)) 
# ('1', '2', "'2010-07-24 19:33:59'") 

PS. Con respecto a Bobby Tables: para el uso normal de MySQLdb, no tiene que escapar manualmente de los argumentos. Simplemente use argumentos parametrizados cuando llame al cursor.execute, y MySQLdb citará automáticamente los argumentos por usted.

Por ejemplo:

sql='insert into students (name,grade,date) values (%s, %s, %s)' 
args=("Robert'); DROP TABLE Students; --",60,now) # no manual quotation necessary 
cursor=connection.cursor() 
cursor.execute(sql,args) 
+0

Intenté escapar con el nombre de Little Bobby Tables, y funcionó. Pero, sabiendo que 'cursor.execute()' escapa automáticamente también es tranquilizador. ¿Está en esa página de documentación vinculada a David Zaslavsky? No lo vi allí ... Pero puede que me lo haya perdido. – eje211

+0

Si lee la tira XKCD, el nombre real de Bobby Tables es: "Robert"); Estudiantes DROP TABLE; - ". Ese es un nombre aterrador para poner en una base de datos. Pero un buen caso de prueba. – eje211

+0

@ eje211: Su pregunta con respecto a en qué parte de la documentación explica la cotización automática de los parámetros es buena. Lo mejor que he podido encontrar es 'No se le debe exigir al cliente que" escape "el valor para que pueda ser utilizado. Consulte http://www.python.org/dev/peps/pep-0249/. – unutbu

2

En realidad, es mejor utilizar la interfaz de nivel superior, MySQLdb. (Consulte el user's guide)

Las funciones _mysql son en realidad solo envoltorios alrededor de la API de C. Se supone que son un detalle de implementación, el tipo de cosas que ni siquiera aparecerían en la documentación de PHP. Los desarrolladores los dejan poco documentados a propósito para desalentar a las personas a usarlos innecesariamente, y también porque pueden consultar el MySQL C API documentation para la función equivalente, que es bastante más completa.

+0

Esa página de documentación es lo que miré primero, pero esas funciones _mysql son lo único que la página menciona acerca de cómo escapar de los datos. Recuerdo muy bien el caso aterrador de Little Bobby Tables: . ¿Qué pasa si Little Bobby Tables aparece en MI base de datos? Oh, el terror! – eje211

+0

Lo sé, bueno, lo bueno de MySQLdb es que en el uso normal, maneja escapes automáticamente, por lo que no hay forma de obtener una inyección SQL cuando se usa la interfaz de nivel superior. –

Cuestiones relacionadas