2009-10-14 24 views
8

Necesito generar una lista de instrucciones de inserción (para postgresql) a partir de archivos html, ¿hay una biblioteca disponible para que python me ayude a escapar y citar los nombres/valores correctamente? en PHP utilizo PDO para escanear y citar, ¿hay alguna biblioteca equivalente para python?Generar instrucciones SQL con python

Editar: Necesito para generar un archivo con las sentencias SQL para su ejecución posterior

+7

Generar "declaraciones SQL simples" con datos en línea es inherentemente propenso a fallas de seguridad por razones tan abstractas como diversas interpretaciones de caracteres Unicode entre el motor de la base de datos y la biblioteca que hace la generación. NO es algo que debes intentar hacer. El resultado, por lo tanto, debe redactarse y pasarse a la API de su base de datos como una cadena de consulta/lista de datos combinada. SQLAlchemy automatizará esto. –

+0

Entiendo, pero el caso de uso fue la generación de un archivo SQL que se ejecutará más tarde – Jeffrey04

+0

http://stackoverflow.com/questions/309945/how-to-quote-a-string-value-explicitly-python-db-api- psycopg2 –

Respuesta

2

Por robustez, recomiendo el uso de declaraciones preparadas para enviar valores introducidos por el usuario, sin importar el idioma que utilice. :-)

+0

¿ya hay una biblioteca para hacerlo? quiero declaraciones SQL simples como salida :) :) – Jeffrey04

1

El python db api 2.0 tiene un método ".execute" para objetos de conexión. Puede especificar parámetros (use una coma NO un signo% para separar los parámetros de la cadena de consulta) con esta función.

10

SQLAlchemy proporciona a robust expression language para generar SQL de Python.

Como cualquier otra capa de abstracción bien diseñada, sin embargo, las consultas que genera insertan datos a través de variables de vinculación en lugar de intentar mezclar el lenguaje de consulta y los datos que se insertan en una sola cadena. Este enfoque evita las vulnerabilidades de seguridad masivas y, por lo demás, es lo correcto.

+0

El enlace está muerto. Creo que este es el documento relacionado: http://docs.sqlalchemy.org/en/latest/core/expression_api.html – Chris

+0

@phasetwenty, gracias, actualizado (cinco años después, heh). –

+0

Creo que está muerto una vez más –

1

Citar parámetros manualmente en general es una mala idea. ¿Qué pasa si hay un error al escapar de las reglas? ¿Qué pasa si el escape no coincide con la versión usada de DB? ¿Qué sucede si se olvida de escapar de algún parámetro o se supone erróneamente que no puede contener datos que requieren escaparse? Eso puede causar vulnerabilidad de inyección SQL. Además, DB puede tener algunas restricciones en la longitud de la instrucción SQL, mientras que usted necesita pasar grandes porciones de datos para la columna LOB. Por eso Python DB API y la mayoría de las bases de datos (módulo API Python DB transparente escaparán parámetros, si la base de datos no es compatible con este, como lo hizo a principios MySQLdb) permiten el paso de parámetros separados de declaración:

.execute (funcionamiento [, parámetros])

+2

Entiendo, pero solo quiero una lista de instrucciones sql (no las ejecuta) – Jeffrey04

13

Sé que esta es una vieja pregunta, pero a menudo he querido lo que parece que el OP quiere: una biblioteca MUY simple para generar SQL básico.

Las siguientes funciones hacen justamente eso. Les asigna un nombre de tabla y un diccionario que contiene los datos que desea usar y devuelven la consulta SQL para la operación que necesita.

Los pares clave/valor representan nombres de campo y valores en las filas de la base de datos.

def read(table, **kwargs): 
    """ Generates SQL for a SELECT statement matching the kwargs passed. """ 
    sql = list() 
    sql.append("SELECT * FROM %s " % table) 
    if kwargs: 
     sql.append("WHERE " + " AND ".join("%s = '%s'" % (k, v) for k, v in kwargs.iteritems())) 
    sql.append(";") 
    return "".join(sql) 


def upsert(table, **kwargs): 
    """ update/insert rows into objects table (update if the row already exists) 
     given the key-value pairs in kwargs """ 
    keys = ["%s" % k for k in kwargs] 
    values = ["'%s'" % v for v in kwargs.values()] 
    sql = list() 
    sql.append("INSERT INTO %s (" % table) 
    sql.append(", ".join(keys)) 
    sql.append(") VALUES (") 
    sql.append(", ".join(values)) 
    sql.append(") ON DUPLICATE KEY UPDATE ") 
    sql.append(", ".join("%s = '%s'" % (k, v) for k, v in kwargs.iteritems())) 
    sql.append(";") 
    return "".join(sql) 


def delete(table, **kwargs): 
    """ deletes rows from table where **kwargs match """ 
    sql = list() 
    sql.append("DELETE FROM %s " % table) 
    sql.append("WHERE " + " AND ".join("%s = '%s'" % (k, v) for k, v in kwargs.iteritems())) 
    sql.append(";") 
    return "".join(sql) 

Lo usa como tal.Sólo tienes que darle un nombre de tabla y un diccionario (o utilizar la función de kwargs ** Python):

>>> upsert("tbl", LogID=500, LoggedValue=5) 
"INSERT INTO tbl (LogID, LoggedValue) VALUES ('500', '5') ON DUPLICATE KEY UPDATE LogID = '500', LoggedValue = '5';" 

>>> read("tbl", **{"username": "morten"}) 
"SELECT * FROM tbl WHERE username = 'morten';" 

>>> read("tbl", **{"user_type": 1, "user_group": "admin"}) 
"SELECT * FROM tbl WHERE user_type = '1' AND user_group = 'admin';" 

pero cuidado con los ataques de inyección SQL

Mira lo que sucede cuando un usuario malicioso de su código hace esto:

>>> read("tbl", **{"user_group": "admin'; DROP TABLE tbl; --"}) 
"SELECT * FROM tbl WHERE user_group = 'admin'; DROP TABLE tbl; --';" 

es fácil de hacer su propio ORM improvisada, sino que sólo te dan lo que ver - que tiene que escapar de la entrada used mismo :)

Cuestiones relacionadas