problema de novato

Marcos Sánchez Provencio rapto en arrakis.es
Vie Mar 18 10:42:27 CET 2005


El modo correcto de usar sql desde programas (con cualquier lenguaje, no
sólo Python) implica no meter valores dentro del sql; en lugar de cada
valor se mete una marca de parámetro (en pyPgSQL es %s). Luego, al hacer
la llamada al servidor, se le indica, por orden en este caso, el valor
de cada parámetro. Lo he dicho en otros mensajes, pero lo repito porque
me parece muy importante. El código quedaría así:

a=c.fetchall()
# 0: OID de la tabla
# 1: nombre de la tabla (==tbname)
# 2: lista de claves ajenas
# 3: OID de la tabla referenciada
# 4: nombre de la tabla refenciada
# 5: lista de claves referenciadas
for i in a:
  for t in range(len(i[2])):
    d.execute(""" select attname
      from pg_attribute
      where attnum=%s 
      and attrelid=%s 
    """,(i[2][t],i[0]))
    b=d.fetchall()
    for q in b:
      print "Nombre:",q[0]

Hay que fijarse especialmente en:
* Se usa %s sin comillas, independientemente del tipo de parámetro
(cadena, número, fecha...)
* No se usa % para 'montar' el sql final, los %s tienen que llegar al
servidor.

Ventajas de este sistema:
* No hay problemas con las comillas en los valores de texto (por lo que
se evitan los ataques de inyección de SQL)
* Se aumenta el rendimiento al optimizar el paso de parámetros y
permitir al optimizador de consultas reutilizar sql de una llamada a
otra.
* Se escribe menos. Esto es Python :-) 
* Se evita el infierno del formato de las fechas.

Espero no resultar pesado :-)

El mié, 16-03-2005 a las 16:27 +0100, J. Manuel Velasco escribió:
> Buenas, el siguiente bloque de codigo me da el 
> error que pongo despues:
> 
>       a=c.fetchall()
> 	  # 0: OID de la tabla
> 	  # 1: nombre de la tabla (==tbname)
> 	  # 2: lista de claves ajenas
> 	  # 3: OID de la tabla referenciada
> 	  # 4: nombre de la tabla refenciada
> 	  # 5: lista de claves referenciadas
>       for i in a:
>          for t in range(len(i[2])):
>             d.execute(""" select attname from 
> pg_attribute where attnum='%s' and attrelid='%s' 
> """)%(i[2][t],i[0])
>             b=d.fetchall()
>             for q in b:
>                print "Nombre:",q[0]
> 
> y el error...
> 
>     d.execute(""" select attname from pg_attribute 
> where attnum='%s' and attrelid='%s' """)%(i[2]
> [t],i[0])
>   File "/usr/lib/python2.3/site-packages/pyPgSQL/
> PgSQL.py", line 3072, in execute
>     raise OperationalError, msg
> libpq.OperationalError: ERROR:  pg_atoi: error in 
> "%s": can't parse "%s"
> 
> Si en lugar de ejecutar la consulta, lo que hago 
> es que me muestre por pantalla la consulta, me lo 
> parsea bien y el resultado lo pruebo a pelo en 
> psql y me hace bien la consulta.
> 
> Alguna sugerencia?
> Gracias.
> 
> _______________________________________________
> Python-es mailing list
> Python-es en aditel.org
> http://listas.aditel.org/listinfo/python-es




Más información sobre la lista de distribución Python-es