Massimo, I created a small test to try your function:
db.define_table('carrier', Field('name', type='string'), Field('description', type='string') ) db.carrier.name.requires = IS_NOT_IN_DB(db(db.carrier.id > 0), 'carrier.name') db.define_table('manufacturer', Field('name', type='string'), Field('country', type='string') ) db.manufacturer.name.requires = IS_NOT_IN_DB(db(db.manufacturer.id > 0), 'manufacturer.name') db.define_table('phone', Field('model', type='string'), Field('manufacturer', db.manufacturer), Field('carrier', db.carrier) ) db.phone.manufacturer.requires = IS_IN_DB(db, 'manufacturer.id', '%(name)s') db.phone.carrier.requires = IS_IN_DB(db, 'carrier.id', '%(name)s') def delete_linked(query, table=db.carrier): ids = [t.id in db(query).select(db.table.id)] for field in table._referenced_by: db(field._table._id.belongs(ids)).delete() db.carrier._before_delete.append(delete_linked) I can create an Apple iPhone on Verizon and an Apple iPhone on Sprint. If I run this under sqlite and I delete the carrier 'Sprint' I see one of the phones deleted as well (even without the '_before_delete' event which makes sense since that's the default behavior). However if I run this under GAE: - Without the '_before_delete' event the carrier 'Sprint' is deleted but not the phone. This is expected since cascading doesn't work. - With the '_before_delete' event (code just as above) *nothing* gets deleted, not even the carrier. I can see it disappear from the list but if I refresh the page it comes right back. I can also verify the record is still there by looking at the GAE admin page (Datastore viewer). Also, none of the phones are deleted either. Am I missing something? Also, when you say that if I delete too many records the operation may fail midway... is that a GAE limitation? Is the 1000 record limit I've read somewhere about? Thanks, Julian On Saturday, November 17, 2012 1:06:01 PM UTC-6, Massimo Di Pierro wrote: > > You can try something like > > def delete_linked(query, table=table): > ids = [t.id in db(query).select(db.table.id)] > for field in table._referenced_by: > db(field._table._id.belongs(ids)).delete() > > db.table._before_delete.append(delete_linked) > > but you will run into consistency problems. If there are too many records > this may fail midway. > > On Wednesday, 14 November 2012 19:07:02 UTC-6, Julian Sanchez wrote: >> >> Hi Everyone!! Long time lurker & first time posting... >> >> I am working on a simple application that I intend to deploy in GAE. I >> have a few tables with fields that reference other tables which by default >> enables the ondelete=CASCADE behavior. This works fine when I run the app >> locally using sqlite as the database. >> I believe GAE doesn't support cascading deletes natively. >> I presume web2py doesn't support cascading deletes when running under GAE >> because I don't see that happening. When I delete a row (rendered through >> SQLFORM.grid) only that row is deleted an all dependent tables remain >> untouched. >> >> The problem I have is that I can't find a way for me to implement the >> cascading behavior manually. I added a 'ondelete=mydelete' event for the >> SQLFORM.grid where I do the manual delete of the dependent tables and >> commit in the database, but that doesn't seem to work either. I searched >> through this forum but didn't find any suggestions either. Any suggestions >> as to what could I do to solve this?? Do I have to stay away from >> SQLFORM.grid to avoid this problem? >> >> Many Thanks!! >> Julian >> >> I am using web2py Version 2.2.1 (2012-10-21 16:57:04) stable on OS X >> Mountain Lion and GoogleAppEngineLauncher version 1.7.3 (1.7.3.333) >> > --