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.