Hello,

I have noticed that virtual fields are painfully slow.
Here is a good way to replace them on a SQL server.
I tested it on both mysql and postgres.

suppose you have the following table:

db.define_table('numbers', Field('a', 'integer'), Field('b', 'integer'))

you can add a virtual field:

class MyVF(object):
  def aplusb(self):
    return self.a + self.b

db.numbers.virtualfields.append(MyVF)

If the virtual field is something more complex (eg.  subqueries) and
the table has more than a few record,
you would end on your knee asking your server not to die each time you
query that table...

Here is a simple solution:

db.define_table('numbers', Field('a', 'integer'), Field('b', 'integer'))

# create the view if it does not exist yet
if not db.executesql("select * from information_schema.tables where
table_name='numbers_v' limit 1;"):
  db.executesql("""create view numbers_v as
select numbers.*, numbers.a + numbers.b as aplusbs from numbers""")

# inform web2py about the view (just add the computed field the others
can be inherited)
db.define_table('numbers_v', db.numbers, Field('aplusb', 'integer'),
migrate=False)
# alias the view
numbers=db.numbers_v.with_alias('numbers')

now you can use db.numbers_v anywhere you would use db.numbers just
make use of the alias:


a_set_of_sums=db(numbers.id>0).select(numbers.aplusb)

enjoy the speed

mic

Reply via email to