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)
>>>>>>>>
>>>>>>>
--