Estoy tratando de actualizar algunos valores en una base de datos. El usuario puede dar la fila que se debe cambiar. La entrada del usuario, sin embargo, es una cadena. Cuando intento analizar esto en el conector MySQL con python, aparece un error debido a los apóstrofes. El código que tengo hasta ahora es:

import mysql.connector

conn = mysql.connector
conn = connector.connect(user=dbUser, password=dbPasswd, host=dbHost, database=dbName)
    cursor = conn.cursor()
cursor.execute("""UPDATE Search SET %s = %s WHERE searchID = %s""", ('maxPrice', 300, 10,))

Recibo este error

mysql.connector.errors.ProgrammingError: 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''maxPrice' = 300 WHERE searchID = 10' at line 1

¿Cómo me deshago de los apóstrofes? Porque creo que están causando problemas.

2
Joost Luijben 1 mar. 2018 a las 00:31

4 respuestas

La mejor respuesta

Como se señaló, no puede prepararlo usando un campo.

Quizás la forma más segura es permitir solo aquellos campos que se esperan, p.

#!/usr/bin/python

import os

import mysql.connector

conn = mysql.connector.connect(user=os.environ.get('USER'),
                               host='localhost',
                               database='sandbox',
                               unix_socket='/var/run/mysqld/mysqld.sock')

cur = conn.cursor(dictionary=True)
query = """SELECT column_name
           FROM information_schema.columns
           WHERE table_schema = DATABASE()
           AND table_name = 'Search'
        """

cur.execute(query)
fields = [x['column_name'] for x in cur.fetchall()]

user_input = ['maxPrice', 300, 10]

if user_input[0] in fields:
    cur.execute("""UPDATE Search SET {0} = {1} WHERE id = {1}""".format(user_input[0], '%s'),
                tuple(user_input[1:]))

print cur.statement

Huellas:

UPDATE Search SET maxPrice = 300 WHERE id = 10

Dónde:

mysql> show create table Search\G
*************************** 1. row ***************************
Search
CREATE TABLE `Search` (
  `id` int(11) DEFAULT NULL,
  `maxPrice` float DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1
Cez 28 feb. 2018 a las 22:03

El nombre de una columna no es un parámetro. Ponga el nombre de la columna maxPrice directamente en su SQL.

cursor.execute("""UPDATE Search SET maxPrice = %s WHERE searchID = %s""", (300, 10))

Si desea utilizar el mismo código con diferentes nombres de columna, deberá modificar la cadena en sí.

sql = "UPDATE Search SET {} = %s WHERE searchID = %s".format('maxPrice')
cursor.execute(sql, (300,10))

Pero tenga en cuenta que esto no está a salvo de la inyección de la forma en que lo están los parámetros, así que asegúrese de que el nombre de su columna no sea una cadena de entrada del usuario ni nada por el estilo.

1
khelwood 28 feb. 2018 a las 21:38

No puede enlazar dinámicamente nombres de objetos (p. Ej., Columnas), solo valores. Si esa es la lógica que está tratando de lograr, tendría que recurrir a la manipulación / formateo de cadenas (con todos los riesgos de ataques de inyección SQL que la acompañan). P.ej.:

sql = """UPDATE Search SET {} = %s WHERE searchID = %s""".format('maxPrice')
cursor.execute(sql, (300, 10,))
1
Mureinik 28 feb. 2018 a las 21:38

No puedes hacerlo así. Debe colocar el nombre de la columna en la cadena antes de llamar a cursor.execute. Los nombres de columna no se pueden usar al transformar variables en cursor.execute.

Algo como esto funcionaría:

sql = "UPDATE Search SET {} = %s WHERE searchID = %s".format('maxPrice')

cursor.execute(sql, (300, 10,))
1
Tim Shaffer 28 feb. 2018 a las 21:38