Thanks,

hm, ok, my usecase is more problematic,


db.define_table('Product',
    Field('name',),
    Field('price', 'decimal(10,2)'),
    Field('quantity', 'integer'),
    Field('*quantity_sold*', 'integer'), # this could be virtual - but then
it does not play with queries...
)

I want to refresh *quantity_sold* after each Purchase (insert/update/delete)
but after delete I'd like to still access which product it has been?
if I do it before delete, the purchace is still there - and my aggregate
function sums it (though I need it gone) ...

db.define_table('Purchase',
    Field('product', db.Product),
    Field('quantity', 'integer'),
)

def update_Product_quantity_from_Purchase( purchase ):
    q_sum = db.Purchase.quantity.sum()
    quantity_sold =
db(db.Purchase.product== purchase.product ).select(q_sum).first()[q_sum] or
0
   db.Product[purchase.product].update_record( *quantity_sold*
=quantity_sold )


db.Pardavimai._after_insert.append( lambda
f,id: update_Product_quantity_from_Purchase(f) )
db.Pardavimai._after_update.append( lambda
s,f: update_Product_quantity_from_Purchase(s.select()[0]) )
db.Pardavimai._after_delete.append( lambda
s: update_Product_quantity_from_Purchase(s.select()[0]) ) #ERR

***
Ha, while writing I came up with workaround -  _before_delete
I add extra parameter to my update_Product... function, which tells that
purchase stuff should be subtracted in advance (as it will be detelted)

def update_Product_quantity_from_Purchase( purchase, deleting=False ):
   ...
   if deleting:
        quantity_sold -= purchace.quantity
   db.Product[purchase.product].update_record( *quantity_sold*=quantity_sold
 )

db.Pardavimai._before_delete.append( lambda
s: update_Product_quantity_from_Purchase(s.select()[0], True) ) #OK

***
ps.: Maybe similar functionality could be extended for "compute'd" field?
If it knew what foreign tables&fields it depends on, the triggers/callbacks
could be added automatically?




On Thu, May 9, 2013 at 2:06 AM, Anthony <[email protected]> wrote:

> If the query only has that one condition, then you can do:
>
> s.query.second
>
> A Set object has a "query" attribute, which is a Query object, and a Query
> object has "op", "first", and "second" attributes. So, s.query gets the
> Query object of the Set, and s.query.second gets the second operand of the
> "==" operator. If instead you have multiple conditions in the query, keep
> in mind that the operands of the "&" operator are themselves Query objects.
> So, if you have:
>
> set = db((db.person.id > 10) & (db.person.name.startswith('A')))
>
> you can extract the 10 from the first part of the query via:
>
> set.query.first.second
>
> In that case, set.query.first itself returns a Query (i.e., db.person.id> 
> 10), so set.query.first.second gives you the 10.
>
> Keep in mind that these properties of Set and Query are internal and not
> part of the API, so this isn't guaranteed to remain backward compatible.
>
> Another option is to pass the Set to the str() function, which generates a
> string that contains the SQL produced by the query. You could then do some
> parsing of that string to get what you want. For example, in this case you
> get:
>
> >>> str(db(db.person.id == 1))
> '<Set (person.id = 1)>'
>
> You can use a regex to get the 1 from that string.
>
> Anthony
>
>
> On Wednesday, May 8, 2013 6:10:05 PM UTC-4, Jurgis Pralgauskis wrote:
>>
>> Hi,
>>
>> I look at example:
>> http://www.web2py.com/book/**default/chapter/06#before-and-**
>> after-callbacks<http://www.web2py.com/book/default/chapter/06#before-and-after-callbacks>
>>
>> how can I find out what is the value of person.id from the set without
>> select?
>> (<Set (person.id = 1)>,)
>>
>> as I tried:
>> s.select(..)[0]   # it worked for update
>> but got
>>
>> Traceback (most recent call last):
>>   File "/home/nijole/Downloads/**EasyVet/web2py/gluon/**restricted.py", line 
>> 212, in restricted
>>     exec ccode in environment
>>   File 
>> "/home/nijole/Downloads/**EasyVet/web2py/applications/**apskaitele/controllers/**appadmin.py"
>>  
>> <http://localhost:8000/admin/default/edit/apskaitele/controllers/appadmin.py>,
>>  line 569, in <module>
>>   File "/home/nijole/Downloads/**EasyVet/web2py/gluon/globals.**py", line 
>> 194, in <lambda>
>>     self._caller = lambda f: f()
>>   File 
>> "/home/nijole/Downloads/**EasyVet/web2py/applications/**apskaitele/controllers/**appadmin.py"
>>  
>> <http://localhost:8000/admin/default/edit/apskaitele/controllers/appadmin.py>,
>>  line 304, in update
>>     if form.accepts(request.vars, session):
>>   File "/home/nijole/Downloads/**EasyVet/web2py/gluon/sqlhtml.**py", line 
>> 1398, in accepts
>>     self.table._db(qry).delete()
>>   File "/home/nijole/Downloads/**EasyVet/web2py/gluon/dal.py", line 9821, in 
>> delete
>>     ret and [f(self) for f in table._after_delete]
>>   File 
>> "/home/nijole/Downloads/**EasyVet/web2py/applications/**apskaitele/models/db.py"
>>  <http://localhost:8000/admin/default/edit/apskaitele/models/db.py>, line 
>> 329, in <lambda>
>>     db.Pardavimai._after_delete.ap**pend( lambda s: 
>> update_SandelioProduktai_**likutis_from_Pardavimai(s.sele**ct(db.Pardavimai.sandelio_**produktas)[0])
>>  )
>>   File "/home/nijole/Downloads/**EasyVet/web2py/gluon/dal.py", line 10075, 
>> in __getitem__
>>     row = self.records[i]
>> IndexError: list index out of range
>>
>>
>>
>>  --
>
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "web2py-users" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/web2py/M4_5THMHzH0/unsubscribe?hl=en.
> To unsubscribe from this group and all its topics, send an email to
> [email protected].
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
>



-- 
Jurgis Pralgauskis
tel: 8-616 77613;
Don't worry, be happy and make things better ;)
http://galvosukykla.lt

-- 

--- 
You received this message because you are subscribed to the Google Groups 
"web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to