'NoneType' object is unsubscriptable

129 views
Skip to first unread message

BlackLion

unread,
Apr 30, 2012, 11:01:56 AM4/30/12
to web2py-...@googlegroups.com
tengo un problema serio en la aplicación que estoy haciendo deseo mostrar un reporte mensual de producción y lo hago de la siguiente manera: le pregunto al usuario el rango de fechas (desde-hasta) y las guardo en 2 variables 'finicio' y 'ffin', y tambien le pregunto el turno de producción 'turno', una vez hecho esto hago algo así:
date = finicio
while date <= ffin:
   t_l10_co = db((lf == date) & (lt == turno)).select(db.logo.c10clipon)
   aj = t_l10_co.last()
   l10co = aj['c10clipon']
   suma=suma+l10co
   date = datetime.timedelta(1)
Pensé que así funcionaria pero me da error cuando pasa por las fechas donde se carga información por ser día no laboral, el error es este:

 Traceback (most recent call last):
  File "gluon/restricted.py", line 205, in restricted
File "C:/Omar/web2py/applications/gestpro/controllers/default.py", line 682, in <module>
File "gluon/globals.py", line 173, in <lambda>
File "C:/Omar/web2py/applications/gestpro/controllers/default.py", line 650, in reportemensual
TypeError: 'NoneType' object is unsubscriptable
entiendo el error, lo que deseo es un forma de resolverlo ya que no se de que otra forma podré hacer el reporte mensual sin tener que estar llenando las tablas con ceros automáticamente 

Alan Etkin

unread,
Apr 30, 2012, 11:49:06 AM4/30/12
to web2py-...@googlegroups.com
No sé cómo es el flujo del reporte (qué va, cuándo y cómo), pero por el código que mostrás, la falla parece ser que cuando la consulta que hace el bucle devuelve una secuencia de registros vacía, al pedir el valor del campo de un registro inexistente genera la excepción. Lo más sencillo sería omitir el error y continuar (con un bloque try-except o comprobando que el resultado de la consulta no sea vacío), pero no sé si el reporte lo permite.

Por ejemplo, para omitir el registro nulo es algo así:

Declaración del bucle:
    Si t_l10_co no es None:
        ...
        date = <dato>

BlackLion

unread,
Apr 30, 2012, 12:05:08 PM4/30/12
to web2py-...@googlegroups.com
ok pero que valor compruebo que no sea None, "aj = t_l10co.last()"? Porque una vez que trato de asignarle ese contenido a una variable me da la excepción 

Luis Díaz

unread,
Apr 30, 2012, 12:15:47 PM4/30/12
to web2py-...@googlegroups.com
puedes hacer un len(aj) > 0
de esta forma sabes si extrajo registros.

la otra cosa que te recomendaría es colocar nombres de variables mas
descriptivos..
lo único que me quedo claro fue "suma"... y en realidad suma de?
debería tener un nombre descriptivo del valor que contiene.. no de lo
que se hace con ella..


Díaz Luis
Analista Programador Facultad de Odontología UC
http://www.about.me/diazluis
User Linux 532223

Jose

unread,
Apr 30, 2012, 12:53:37 PM4/30/12
to web2py-...@googlegroups.com

Lo que creo que deberías hacer es una consulta que sume y agrupe por fecha. Algo similar a.

suma = db.mi_tabla.mi_campo_a_sumar.sum().with_alias("suma")
qry_fecha_inicio = (db.mi_tabla.fecha >= fecha_inicio)
qry_fecha_fin = (db.mi_tabla.fecha <= fecha_fin)
qry_turno = (db.mi_tabla.turno==turno)

registros = db(qry_fecha_inicio & qry_fecha_fin & qry_turno).select(db.mi_tabla.fecha, otros_campos, suma, groupby=db.mi_tabla.fecha, orderby=db.mi_tabla.fecha)

No lo probé, pero debería funcionar

Saludos
Jose

mas info:

http://www.web2py.com/books/default/chapter/29/6#sum,-min,-max-and-len
http://www.web2py.com/books/default/chapter/29/6#orderby,-groupby,-limitby,-distinct

BlackLion

unread,
Apr 30, 2012, 1:54:40 PM4/30/12
to web2py-...@googlegroups.com
trate de hacer lo que me indicaste y me dijo 

object of type 'NoneType' has no len()

BlackLion

unread,
Apr 30, 2012, 2:04:55 PM4/30/12
to web2py-...@googlegroups.com
Y luego de hacer esto como obtengo lo que contiene el query, así:
a = registros.last()
contenido = a['mi_campo_a_sumar'] 

Alan Etkin

unread,
Apr 30, 2012, 8:53:01 PM4/30/12
to web2py-...@googlegroups.com
El tema es este: si  t_l10_co no devolvió resultados (instancia de Rows sin registros), al hacer .last() devuelve None. Luego, para este caso tendrías que continuar el bucle sin procesar datos, evitando el error, o reemplazar la propiedad del registro inexistente con un dato válido por defecto (o cualquier otra cosa que evite la excepción). Para la primera opción sería algo así:


while date <= ffin:
   t_l10_co = db((lf == date) & (lt == turno)).select(db.logo.c10clipon)
   aj = t_l10_co.last()
   # procesar datos sólo si la consulta no es vacía.
   if aj is not None:
     l10co = aj['c10clipon']
     suma=suma+l10co
     date = datetime.timedelta(1)

BlackLion

unread,
May 2, 2012, 10:53:51 AM5/2/12
to web2py-...@googlegroups.com
Solucione el problema utilizando try-except, el codigo quedo más largo pero no hay rollo muchas gracias

BlackLion

unread,
May 2, 2012, 12:10:46 PM5/2/12
to web2py-...@googlegroups.com
Surgio una falla inesperada y es que cuando el programa esta ejecutando esto:
ex20 = db((sbf == date) & (sbt == turno)).select(db.soldadura_b.extintor20)
c = ex20.last()
try:
e20 = c['extintor20']
except:
e20 = 0
s50 = s50+e20
me da este error: 

unsupported operand type(s) for +: 'int' and 'NoneType'

no entiendo por qué, porque si la variable es NoneType le estoy asignando un valor entero = 0, si alguien me puede ayudar

Sebastian Bassi

unread,
May 2, 2012, 12:35:31 PM5/2/12
to web2py-...@googlegroups.com
2012/5/2 BlackLion <omar.f...@gmail.com>:
> s50 = s50+e20
> me da este error:
>
> unsupported operand type(s) for +: 'int' and 'NoneType'
>
> no entiendo por qué, porque si la variable es NoneType le estoy asignando un
> valor entero = 0, si alguien me puede ayudar

Por empezar no uses "try" asi solo, pone try tipo_de_error. Si no
sabes cual es el tipo de error, correlo una vez sin try y miralo,
luego ponelo en el try, asi te aseguras que se active solo por eso y
no por otra cosa.
Ahora en donde asignas s50?

BlackLion

unread,
May 2, 2012, 1:50:21 PM5/2/12
to web2py-...@googlegroups.com
Al comienzo de esa funcion digo que s50 = 0, y el tipo de error que da sin el try es que dice que 'NoneType is unsuscriptable', sera que debo colocar algo así:
except NoneType:
                          e20 = 0
A ver si así hace lo que yo quiero, lo que me intriga es que hace unos 30 minutos sin especificar ni el try ni el except, funcionaba bien, pero ahora no.

Alan Etkin

unread,
May 3, 2012, 9:15:48 AM5/3/12
to web2py-usuarios
> sera que debo colocar
> algo así ...

Esta es una forma:

try:
...
except TypeError:
e20 = 0

> unsupported operand type(s) for +: 'int' and 'NoneType'

El error que te da actualmente es porque uno de los dos objetos de la
suma
es de tipo None. Necesitarías depurar el código para saber cuándo se
cambia a None (probablemente cuando
llamás a una función de la DAL como .select() o .last() o
registro["campo"])
y establecer el valor numérico por defecto que necesites antes de que
se haga la operación.

Omar Fariñez

unread,
May 3, 2012, 3:13:57 PM5/3/12
to web2py-...@googlegroups.com
si ya vi que hay una diferencia cuando dice que es unsuscriptable es porque no hay nada, por ejemplo si pido un reporte en una fecha donde no se haya guardado nada, es decir, fines de semana feriados, etc. Pero si lo que esta guardado es un 'None' el query si lo trae y por eso no hace la suma. Gracias por la ayuda
Reply all
Reply to author
Forward
0 new messages