[web2py] Re: Newbie: Cascading deletes with SQLFORM.grid and GAE

2012-11-27 Thread Julian Sanchez
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

[web2py] Re: Newbie: Cascading deletes with SQLFORM.grid and GAE

2012-11-27 Thread howesc
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 

[web2py] Re: Newbie: Cascading deletes with SQLFORM.grid and GAE

2012-11-25 Thread Julian Sanchez
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 p

[web2py] Re: Newbie: Cascading deletes with SQLFORM.grid and GAE

2012-11-24 Thread howesc
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

[web2py] Re: Newbie: Cascading deletes with SQLFORM.grid and GAE

2012-11-24 Thread Julian Sanchez
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

[web2py] Re: Newbie: Cascading deletes with SQLFORM.grid and GAE

2012-11-23 Thread howesc
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)
>

[web2py] Re: Newbie: Cascading deletes with SQLFORM.grid and GAE

2012-11-21 Thread Julian Sanchez
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)
>>
>

-- 





[web2py] Re: Newbie: Cascading deletes with SQLFORM.grid and GAE

2012-11-17 Thread Massimo Di Pierro
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)
>

--