So che questa è una vecchia domanda, ma ho spesso desiderato ciò che sembra l'OP desidera: Una libreria MOLTO semplice per generare SQL di base.
Le funzioni seguenti fanno proprio questo. Dagli un nome di tabella e un dizionario contenente i dati che desideri utilizzare e restituiscono la query SQL per l'operazione necessaria.
Le coppie chiave/valore rappresentano i nomi dei campi e i valori nelle righe del database.
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 si utilizza così.Basta dare un nome di tabella e un dizionario (o usare il ** kwargs caratteristica del pitone):
>>> 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';"
ma attenzione di attacchi SQL injection
Guardate cosa succede quando un utente malintenzionato del codice fa questo:
>>> read("tbl", **{"user_group": "admin'; DROP TABLE tbl; --"})
"SELECT * FROM tbl WHERE user_group = 'admin'; DROP TABLE tbl; --';"
E 'facile fare il proprio ORM di fortuna ma si ottiene solo ciò che si vede - si deve sfuggire l'ingresso da soli :)
Generare "semplici istruzioni SQL" con dati in linea è intrinsecamente soggetto a errori di sicurezza per ragioni astratte come interpretazioni variabili di caratteri Unicode tra il motore di database e la libreria che sta generando. NON è qualcosa che dovresti provare a fare. L'output, quindi, deve essere espresso in frasi e passato all'API del database come stringa di query/lista dati combinata. SQLAlchemy lo automatizzerà. –
Capisco, ma il caso d'uso stava generando un file SQL da eseguire successivamente – Jeffrey04
http://stackoverflow.com/questions/309945/how-to-quote-a-string-value-explicitly-python-db-api- psycopg2 –