PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Générer des instructions SQL avec python

Je sais que c'est une vieille question, mais j'ai souvent voulu ce que l'OP semble vouloir :une bibliothèque TRÈS simple pour générer du SQL de base.

Les fonctions ci-dessous font exactement cela. Vous leur donnez un nom de table et un dictionnaire contenant les données que vous souhaitez utiliser et ils renvoient la requête SQL pour l'opération dont vous avez besoin.

Les paires clé/valeur représentent les noms de champ et les valeurs dans les lignes de la base de données.

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)

Vous l'utilisez comme ça. Donnez-lui simplement un nom de table et un dictionnaire (ou utilisez la fonction **kwargs de 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';"

Mais ATTENTION AUX ATTAQUES D'INJECTION SQL

Regardez ce qui se passe lorsqu'un utilisateur malveillant de votre code fait ceci :

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

Il est facile de créer votre propre ORM de fortune, mais vous n'obtenez que ce que vous voyez - vous devez échapper vous-même à l'entrée :)