Op woensdag 13 augustus 2014 15:00:38 UTC+2 schreef Anthony:
>
> def new_style_virtual_field_test():
>>
>>     db = DAL('sqlite:memory',pool_size=1)
>>>     db.define_table('myorder',
>>>         Field('a','integer'),
>>>         Field('b','integer')
>>>     )
>>>     db.myorder.c = Field.Virtual(lambda row:row.a * row.b)
>>>     db.myorder.insert(a=2,b=3)
>>>     return db().select(db.myorder.ALL).first().as_json()
>>>     # {"a": 2, "id": 1, "b": 3}
>>>
>>
>> Are you sure that's the exact code you have run, because row.a * row.b 
>> is not the correct syntax and should result in an exception as soon as you 
>> do a select.
>>
>
> It is, just tested this. I'm using 2.9.5-stable+timestamp.2014.03.16.02.35.39 
> using python 2.7.3
>

I forgot this was changed -- now AttributeError exceptions in the virtual 
fields function fail silently, simply foregoing the creation of the virtual 
field value for the record (which is why you got no error but didn't see 
the value in the record).
 

>  Instead, it should be:
>  
>
>> db.myorder.c = Field.Virtual('c', lambda row: row.myorder.a * row.myorder
>> .b)
>>
>> In the function, you must include the table name when accessing fields in 
>> the row. Also, note that even when creating the virtual field via 
>> assignment, you should still specify the name of the virtual field within 
>> Field.Virtual() -- otherwise the "name" attribute of the virtual field will 
>> be set to "unknown", which may cause problems in some contexts.
>>
>
> Thanks for the enlightenment. I've tried your change, and now it gives me 
> the proper result. But i don't get your remark about the name attribute. I 
> can't find that in the book for new style virtual classes, can you offer me 
> a pointer? When looking at ">>> db.item.total_price = 
> Field.Virtual(lambda row: row.unit_price*row.quantity)" from the book 
> (mind the table name not being used here either) i thought the name 
> assignment would be automatic by using db.myorder.c 
>

Note, the book code is actually:

db.item.total_price = Field.Virtual(
    'total_price',
    lambda row: row.item.unit_price*row.item.quantity)


Notice the first argument to Field.Virtual is 'total_price'. If you do 
that, then db.item.total_price.name will be 'total_price'. If you don't do 
that, then db.item.total_price.name will be 'unknown', which will cause 
problems in some cases where the field's "name" attribute is used. This is 
not explicitly mentioned in the book, though the book examples do include 
the name explicitly.
 

>         return db().select(db.myorder.a, db.myorder.b, 
>> db.myorder.c).first().as_json()
>>     # <class 'sqlite3.OperationalError'> no such column: None.unknown
>>     # (self=<gluon.dal.SQLiteAdapter object>, *a=('SELECT myorder.a, 
>> myorder.b, None.unknown FROM myorder;',), **b={})
>>     
>>     # where has my C field gone to?     
>>
>  
> Virtual fields are not stored in the database but are calculated after 
> records are pulled from the database, so they are not to be listed in the 
> call to .select().
>

Can a notimplemented exception be justified in such a case?
>

I think that particular exception is for methods within classes that have 
not been implemented. In any case, I don't think this case justifies a new 
custom exception. Should probably just be handled with documentation.

Anthony

-- 
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- 
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 web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to