Python, SQLAlchemy pasan parámetros en connection.execute

Estoy usando SQLAlchemy connection.execute (sql) para transformar los resultados seleccionados en un conjunto de mapas. Tener código siguiente

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 

y por ejemplo

 __sql_to_data(sql_get_scan_candidate) 

me da una buena estructura de datos (por supuesto que estoy usando esto para pequeños conjuntos de datos). Pero para agregar un parámetro a sql, actualmente estoy usando el formato, por ejemplo,

 return __sql_to_data(sql_get_profile.format(user_id)) 

Pregunta ¿Cómo modificar el procedimiento para hacer posible algo como?

 return __sql_to_data(sql_get_profile,user_id) 

El tutorial da un buen ejemplo para esto:

 >>> 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, wendy@aol.com',)] 

Primero, tome su cadena SQL y pásela a sqalchemy.sql.text () . Esto no es necesario, pero probablemente sea una buena idea …

Las ventajas que ofrece text () sobre una cadena simple son el soporte neutral para los parámetros de enlace, las opciones de ejecución por instrucción, así como el comportamiento de escritura de parámetros de resultado y columna, permitiendo que las construcciones de tipo SQLAlchemy desempeñen un papel al ejecutar una instrucción que Se especifica literalmente.

Tenga en cuenta que incluso si no usó text() , NUNCA debe usar sql.format(...) . Esto conduce a un mayor riesgo de ataques de inyección de SQL .

A continuación, puede especificar los argumentos reales usando parámetros de palabras clave para la función execute () que ya ha estado usando.

Ahora, en su ejemplo, tiene una función que envuelve la funcionalidad de ejecución. Por lo tanto, si desea usar esto para múltiples consultas, deberá hacer que los parámetros puedan recibir sus argumentos. Podrías hacer esto bastante simple como un diccionario:

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

values serían un diccionario. Luego, podrías usar tu función como esta …

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

Usar palabras clave como parámetros es solo una forma de especificar los argumentos de la función execute() . Puede leer la documentación de esa función de varias maneras diferentes.