web-dev-qa-db-fra.com

Python, SQLAlchemy passent des paramètres dans connection.execute

J'utilise SQLAlchemy connection.execute (sql) pour transformer les résultats sélectionnés en tableau de cartes. Avoir le code suivant


def __sql_to_data(sql):
    result = []
    connection = engine.connect()
    try:
        rows = connection.execute(sql)
        for row in rows:
            result_row = {}
            for col in row.keys():
                result_row[str(col)] = str(row[col])
            result.append(result_row)
    finally:
        connection.close()
    return result

et par ex.

__sql_to_data(sql_get_scan_candidate)
return __sql_to_data(sql_get_profile.format(user_id))

Question Comment modifier la procédure pour rendre possible quelque chose comme

return __sql_to_data(sql_get_profile,user_id)
22
Denis

Le tutoriel donne un assez bon exemple pour cela:

>>> from sqlalchemy.sql import text
>>> s = text(
...     "SELECT users.fullname || ', ' || addresses.email_address AS title "
...         "FROM users, addresses "
...         "WHERE users.id = addresses.user_id "
...         "AND users.name BETWEEN :x AND :y "
...         "AND (addresses.email_address LIKE :e1 "
...             "OR addresses.email_address LIKE :e2)")
SQL>>> conn.execute(s, x='m', y='z', e1='%@aol.com', e2='%@msn.com').fetchall() 
[(u'Wendy Williams, [email protected]',)]

Tout d'abord, prenez votre chaîne SQL et passez-la à sqalchemy.sql.text () . Ce n'est pas nécessaire, mais c'est probablement une bonne idée ...

Les avantages que text () offre par rapport à une chaîne simple sont une prise en charge neutre pour les paramètres de liaison, les options d'exécution par instruction, ainsi que le comportement de typage des paramètres et des colonnes de résultat, permettant aux constructions de type SQLAlchemy de jouer un rôle lors de l'exécution d'une instruction qui est spécifié littéralement.

Notez que même si vous n'avez pas utilisé text(), vous ne devez JAMAIS utiliser sql.format(...). Cela entraîne un risque accru d'attaques injection SQL .

Ensuite, vous pouvez spécifier les arguments réels à l'aide des paramètres de mot-clé de la fonction execute () que vous avez déjà utilisée.

Maintenant, dans votre exemple, vous avez une fonction qui encapsule la fonctionnalité d'exécution. Donc, si vous souhaitez l'utiliser pour plusieurs requêtes, vous devrez rendre les paramètres capables de recevoir vos arguments. Vous pouvez faire cela assez simplement comme un dictionnaire:

def _sql_to_data(sql, values):
    ...
    conn.execute(sql, values)

values serait un dictionnaire. Vous pourriez alors utiliser votre fonction comme ceci ...

sql = 'SELECT ...'
data = { 'user_id' : 3 }
results = _sql_to_data(sql, data)

L'utilisation de mots clés comme paramètres n'est qu'une façon de spécifier les arguments de la fonction execute(). Vous pouvez lire la documentation pour cette fonction de différentes manières.

49
Mark Hildreth