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.