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

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

def old_style_virtual_field_test1():
>     db = DAL('sqlite:memory',pool_size=1)
>     db.define_table('myorder',
>         Field('a','integer'),
>         Field('b','integer')
>     )
>     class MyVirtualFields(object):
>         def c(self):
>             return self.myorder.a * self.myorder.b
>     db.myorder.virtualfields.append(MyVirtualFields())
>     db.myorder.insert(a=2,b=3)
>     # return db().select(db.myorder.ALL).first().as_json()
>     # {"a": 2, "id": 1, "b": 3}
>     # where is c? 
>

Don't know. When I run the exact code above, I get:

{"a": 2, "c": 6, "b": 3, "id": 1}

     

>     return db().select(db.myorder.a, db.myorder.b, 
> db.myorder.c).first().as_json()
>     # AttributeError: 'Table' object has no attribute 'c'
>
>     # it doesn't ? I thought i declared to be virutally present
>

Old style virtual fields work differently -- they don't result in 
individual "field" attributes being added to the table object. Rather, they 
are stored in the "virtualfields" attribute of the table.
 

>     db.myorder.setvirtualfields(myorder=MyVirtualFields())
>     # <type 'exceptions.AttributeError'> 'Table' object has no attribute 
> 'setvirtualfields'
>     # maybe a bit more clarity in the documentation would be nice. I 
> understand the purpose
>     # but it's easily overlooked.
>

The book seems fairly clear to me on this point. The only example it shows 
using .setvirtualfields() is in the context of creating virtual fields on 
the result of a join, with the following code:

rows.setvirtualfields(order_item=MyVirtualFields())

It then says (highlights added):

Notice how in this case the syntax is different. The virtual field accesses 
both self.item.unit_price and self.order_item.quantity which belong to the 
join select. The virtual field is attached to the rows of the table using 
the setvirtualfields method of the rows object.
 

>     rows = db(db.myorder).select()
>     # now i have to apply them after selecting? That's counter intuitive
>     # i thought it would be in the model, not the controller 
>     rows.setvirtualfields(myorder=MyVirtualFields())
>     # also note the setvirtualfields has to be applied to the rows, not to 
> a single row.
>

There is no need to use .setvirtualfields() in the above example given that 
you are selecting from a single table. The primary purpose of that method 
is when you want to apply virtual fields to the result of a join of 
multiple tables (so, you must apply the virtual fields to the rows rather 
than to an individual table).

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