Error in last stable version when trying to delete through one to many relation

53 views
Skip to first unread message

Lisandro

unread,
Aug 3, 2015, 8:13:45 AM8/3/15
to web2py-users
I've upgraded from version 2.10.3 to last stable version 2.11.2, but after the upgrade, an error is thrown when trying to delete a subset through one to many relation.

Consider the example of the book (table "person", and table "thing", each thing is owned by one person):

This is the error's traceback:

Traceback (most recent call last):
File "/home/gonguinguen/medios/gluon/restricted.py", line 227, in restricted
exec ccode in environment
File "/home/gonguinguen/medios/applications/demo_panel/controllers/contenido.py", line 459, in <module>
File "/home/gonguinguen/medios/gluon/globals.py", line 412, in <lambda>
self._caller = lambda f: f()
File "/home/gonguinguen/medios/gluon/tools.py", line 3583, in f
return action(*a, **b)
File "/home/gonguinguen/medios/applications/demo_panel/controllers/contenido.py", line 436, in _eliminar_borrador
noticia.galeria_contenido.delete()
File "/home/gonguinguen/medios/gluon/packages/dal/pydal/helpers/classes.py", line 348, in __getattr__
raise AttributeError
AttributeError

The error disappears downgrading to version 2.10.3.

Niphlod

unread,
Aug 3, 2015, 11:20:40 AM8/3/15
to web2py-users
an app to reproduce the issue (or at least a model definition!) would be fine to spot the error.

Lisandro

unread,
Aug 3, 2015, 11:33:01 AM8/3/15
to web2py-users
Sorry, this is (part of) my db.py:

db.define_table('contenido', \
 
Field('titulo'), \
 
Field('slug'), \
 
Field('fecha_hora', 'datetime'), \
 
Field('detalle', 'text'), \
 
Field('cuerpo', 'text'), \
 
Field('autor'), \
 
Field('meta_description'))


db
.define_table('galeria_contenido', \
 
Field('contenido', db.contenido, ondelete='NO ACTION'), \
 
Field('orden', 'integer'), \
 
Field('titulo'), \
 
Field('detalle', 'text'))


On the other hand, a controller with a function that tries to delete a "noticia" (spanish for "news"):

def _eliminar_borrador():
    noticia
= db.contenido[request.post_vars.noticia]
    noticia
.galeria_contenido.delete()
    db
(db.contenido.id==noticia.id).delete()
   
return response.json({'success':True})


The line that throws the error is this:
noticia.galeria_contenido.delete()



Here I post again the traceback:
Traceback (most recent call last):
File "/home/gonguinguen/medios/gluon/restricted.py", line 227, in restricted
exec ccode in environment
File "/home/gonguinguen/medios/applications/demo_panel/controllers/contenido.py", line 459, in <module>
File "/home/gonguinguen/medios/gluon/globals.py", line 412, in <lambda>
self._caller = lambda f: f()
File "/home/gonguinguen/medios/gluon/tools.py", line 3583, in f
return action(*a, **b)
File "/home/gonguinguen/medios/applications/demo_panel/controllers/contenido.py", line 436, in _eliminar_borrador
noticia.galeria_contenido.delete()
File "/home/gonguinguen/medios/gluon/packages/dal/pydal/helpers/classes.py", line 348, in __getattr__
raise AttributeError
AttributeError

That sentence is executed without errors if I write it this way:
db(db.galeria_contenido.contenido==noticia.id).delete()


I think both sentences are valid. The first one only fails with web2py 2.11.2, but works ok with 2.10.3.

Niphlod

unread,
Aug 3, 2015, 2:47:18 PM8/3/15
to web2py-users
uhm, I can't reproduce with a minimal model and 2.11.2 ......
what backend are you using ?


web2py
Web Framework
Created by Massimo Di Pierro, Copyright 2007-2015
Version 2.11.2-stable+timestamp.2015.05.30.11.29.46
Database drivers available: psycopg2, pymysql, imaplib, sqlite3, pg8000, pyodbc
WARNING
:web2py:import IPython error; use default python shell
Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> db.define_table('contenido', Field('titulo'))
<Table contenido (id,titulo)>

>>> db.define_table('galeria_contenido', Field('contenido', db.contenido,
ondele
te
='NO ACTION'), Field('titulo'))
<Table galeria_contenido (id,contenido,titulo)>
>>> db.contenido.insert(titulo='test')
1L
>>> db.galeria_contenido.insert(contenido=1, titulo='galeria_1')
1L
>>> db.galeria_contenido.insert(contenido=1, titulo='galeria_2')
2L
>>> db.contenido[1]
<Row {'titulo': 'test', 'id': 1L, 'galeria_contenido': <Set (galeria_contenido.contenido = 1)>}>
>>> contenido_1 = db.contenido[1]
>>> contenido_1
<Row {'titulo': 'test', 'id': 1L, 'galeria_contenido': <Set (galeria_contenido.contenido = 1)>}>
>>> contenido_1.galeria_contenido.delete()
2
>>>



Can you replicate the issue with this ultra-slim model ?


Anthony

unread,
Aug 3, 2015, 3:23:25 PM8/3/15
to web2py-users
Also, note that the error is not related to the delete method -- it is occurring when trying to access

noticia.galeria_contenido

The "galeria_contenido" attribute of the Row object should be a Set object referring to the set of records in db.galeria_contenido that reference this particular row in db.contenido. For some reason, that Set object is not there.

Anthony

Lisandro

unread,
Aug 3, 2015, 5:25:24 PM8/3/15
to web2py-users
I **think** I've found the problem. 
After some tests, I've deduced that the error is thrown when using DAL with lazy_tables=True. 
So when I retrieve a Row from "contenido" table, the returned object does not contain the "galeria_contenido" set. 

Is this a bug? Or I've been using lazy_tables in the wrong way? 
I ask because I've been using this code in production for a while with no errors, but the error only appeared when I upgrade from 2.10.3 to 2.11.2 (haven't checked intermediate versions).

Massimo Di Pierro

unread,
Aug 4, 2015, 11:21:38 AM8/4/15
to web2py-users
good catch! I opened a ticket: https://github.com/web2py/pydal/issues/262

Paolo Valleri

unread,
Aug 17, 2015, 10:34:18 AM8/17/15
to web2py-users
Hi all, 
according to my tests the issue is fixed on master pydal.
@Lisandro, you should use master web2py which points to a version of pydal containing the fix.

Paolo
Reply all
Reply to author
Forward
0 new messages