not - Python MySQLdb TypeError: no todos los argumentos convertidos durante el formateo de cadenas
odoo typeerror not all arguments converted during string formatting (6)
Al ejecutar este script:
#! /usr/bin/env python
import MySQLdb as mdb
import sys
class Test:
def check(self, search):
try:
con = mdb.connect(''localhost'', ''root'', ''password'', ''recordsdb'');
cur = con.cursor()
cur.execute( "SELECT * FROM records WHERE email LIKE ''%s''", search )
ver = cur.fetchone()
print "Output : %s " % ver
except mdb.Error, e:
print "Error %d: %s" % (e.args[0],e.args[1])
sys.exit(1)
finally:
if con:
con.close()
test = Test()
test.check("test")
Me sale un error de:
./lookup
Traceback (most recent call last):
File "./lookup", line 27, in <module>
test.check("test")
File "./lookup", line 11, in creep
cur.execute( "SELECT * FROM records WHERE email LIKE ''%s''", search )
File "/usr/local/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 187, in execute
query = query % tuple([db.literal(item) for item in args])
TypeError: not all arguments converted during string formatting
No tengo idea de por qué. Estoy tratando de hacer consultas parametrizadas, pero no ha sido más que un dolor. Soy algo nuevo para Python, por lo que probablemente sea un problema obvio.
En lugar de esto:
cur.execute( "SELECT * FROM records WHERE email LIKE ''%s''", search )
Prueba esto:
cur.execute( "SELECT * FROM records WHERE email LIKE %s", [search] )
Ver la documentation MySQLdb. El razonamiento es que el segundo parámetro de execute
representa una lista de los objetos que se convertirán, porque podría tener un número arbitrario de objetos en una consulta parametrizada. En este caso, solo tiene uno, pero todavía necesita ser iterable (una tupla en lugar de una lista también estaría bien).
La palabra clave ''%'' es tan peligrosa porque es la causa principal de ''SQL INJECTION ATTACK''.
Entonces solo usas este código.
cursor.execute("select * from table where example=%s", (example,))
o
t = (example,)
cursor.execute("select * from table where example=%s", t)
si quieres probar insertar en la tabla, prueba esto.
name = ''ksg''
age = 19
sex = ''male''
t = (name, age, sex)
cursor.execute("insert into table values(%s,%d,%s)", t)
No entiendo las primeras dos respuestas. Creo que deben ser dependientes de la versión. No puedo reproducirlos en MySQLdb 1.2.3, que viene con Ubuntu 14.04LTS. Probemos. Primero, verificamos que MySQL no acepte apóstrofos dobles:
mysql> select * from methods limit 1;
+----------+--------------------+------------+
| MethodID | MethodDescription | MethodLink |
+----------+--------------------+------------+
| 32 | Autonomous Sensing | NULL |
+----------+--------------------+------------+
1 row in set (0.01 sec)
mysql> select * from methods where MethodID = ''''32'''';
ERROR 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 ''9999'''' '' at line 1
Nop. Probemos el ejemplo que Mandatory publicó usando el constructor de consulta dentro de /usr/lib/python2.7/dist-packages/MySQLdb/cursors.py
donde abrí "con" como una conexión a mi base de datos.
>>> search = "test"
>>> "SELECT * FROM records WHERE email LIKE ''%s''" % con.literal(search)
"SELECT * FROM records WHERE email LIKE ''''test''''"
>>>
No, los apóstrofos dobles hacen que falle. Probemos el primer comentario de Mike Graham, donde sugiere dejar los apóstrofos citando el% s:
>>> "SELECT * FROM records WHERE email LIKE %s" % con.literal(search)
"SELECT * FROM records WHERE email LIKE ''test''"
>>>
Sí, eso funcionará, pero el segundo comentario de Mike y la documentación dice que el argumento para ejecutar (procesado por con.literal) debe ser una tupla (search,)
o una lista [search]
. Puedes probarlos, pero no encontrarás diferencia con el resultado anterior.
La mejor respuesta es ksg97031.
Puedes probar este código:
cur.execute( "SELECT * FROM records WHERE email LIKE ''%s''", (search,) )
Puedes ver la documentación
Según PEP8, prefiero ejecutar SQL de esta manera:
cur = con.cursor()
# There is no need to add single-quota to the surrounding of `%s`,
# because the MySQLdb precompile the sql according to the scheme type
# of each argument in the arguments list.
sql = "SELECT * FROM records WHERE email LIKE %s;"
args = [search, ]
cur.execute(sql, args)
De esta forma, reconocerá que el segundo argumento args
del método de execute
debe ser una lista de argumentos.
Que esto te ayude
cur.execute( "SELECT * FROM records WHERE email LIKE %s", (search,) )
No sé por qué, pero esto funciona para mí. en lugar de usar ''%s''
.