Aha!! I don't know how I missed that before but indeed the event was throwing an exception and GAE kept on going on its merry way. Found a couple of things I was doing wrong. The delete event method takes only one parameter (the query) and once you get the query you can do a straight 'select()' from that and figure out which ID's are being deleted.
Thanks so much for the help!! I appreciate the guidance and coaching. On Tuesday, November 27, 2012 10:39:54 AM UTC-6, howesc wrote: > > Julian, > > can you add logging to your delete_linked method to prove to yourself that > it is being called, and that it is not throwing an exception? that will > help us track down where it's gone astray.... > > thanks! > > cfh > > On Sunday, November 25, 2012 5:43:16 PM UTC-8, Julian Sanchez wrote: >> >> Oh, I see. I thought that were you mentioned logs you were referring to >> the built-in logs inside web2py (I assume there are some?). As far as my >> 'test app' is concerned all there is is the code I posted a couple of posts >> ago. I also added these controllers for testing the deletion of records: >> >> def phones(): >> form = SQLFORM.grid(query=(db.phone.id > 0)) >> return dict(form=form) >> >> def carriers(): >> form = SQLFORM.grid(query=(db.carrier.id > 0)) >> return dict(form=form) >> >> def manufacturers(): >> form = SQLFORM.grid(query=(db.manufacturer.id > 0)) >> return dict(form=form) >> >> >> All I do is invoke those controllers, add a couple of test entries, and >> then delete a carrier that is being referenced by a couple of phones. With >> the _before_delete even nothing gets deleted and nothing special is shown >> in the GAE console. That's what puzzling me. >> >> >> >> On Sunday, November 25, 2012 12:13:41 AM UTC-6, howesc wrote: >>> >>> honestly, i'm not smart enough to use logging.conf. i'm not sure how >>> much of it is GAE overriding things, and how much of it is my inability to >>> read the docs and understand how it works! anyhow, i don't have a >>> logging.conf in my GAE setups, but i use logging extensively and it all >>> seems to show up in the GAE console logs just fine. >>> >>> if you have no logging.conf and you have logging.info statements in >>> your code, can you find the messages in your logs? >>> >>> cfh >>> >>> On Saturday, November 24, 2012 5:29:41 AM UTC-8, Julian Sanchez wrote: >>>> >>>> Are there any specific things I need to do to enable logging under GAE? >>>> This is what I did: >>>> >>>> - renamed the logging.example.conf file to logging.conf >>>> - added an entry for the test app I created above >>>> - removed all references to all handlers except consoleHandler >>>> >>>> Any page I request gives me an "IOError: invalid mode: a" in the GAE >>>> logging console. If I renamed the logging file back to >>>> logging.example.conf then I can request pages and run the app just fine. >>>> >>>> On Friday, November 23, 2012 7:47:26 PM UTC-6, howesc wrote: >>>>> >>>>> can you add some logging in and let us know if there are exceptions? >>>>> >>>>> about the delete limitations - web2py iterates over the set of items >>>>> to delete and deletes them (the version in trunk is improved over the >>>>> last >>>>> release, but both still work). if the set of items to delete is large >>>>> the >>>>> query to get the items to delete may take too long and timeout. in the >>>>> latest released version it actually can timeout before any rows are >>>>> deleted. in the trunk version it will delete at least some rows before >>>>> the >>>>> first timeout (in most cases), so over a series of retries all the rows >>>>> will be deleted. This behavior is all to deal with how GAE implements >>>>> delete, so it is GAE specific. >>>>> >>>>> cfh >>>>> >>>>> >>>>> On Wednesday, November 21, 2012 5:04:32 PM UTC-8, Julian Sanchez wrote: >>>>>> >>>>>> 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) >>>>>>>> >>>>>>> --