instead of default=now use default = request.now also change default = now in modified_on to update=request.now
regards Martin On Wed, Jan 26, 2011 at 1:36 AM, Bernd Rothert <roth...@googlemail.com>wrote: > A table definition from the DAL chapter of the Web2py book: > > db.define_table('person', > Field('uuid', length=64, default=uuid.uuid4()), > Field('modified_on', 'datetime', default=now), > Field('name'), > format='%(name)s') > > "now" usually contains the current datetime from request.now and > that's fine but the default for "uuid" would be identical for all > inserts. Although the example doesn't use the default so it is not a > problem there. > > If you omit the parenthesis behind "default=uuid.uuid4()" and simple > pass the uuid4 function as the default it works as expected - the > default is evaluated at insert time and yields a fresh uuid for each > new record. I assume this is the intended behaviour although I > couldn't find it documented(!?). > > Strangely replacing "default=now" in the same way with e.g. > "default=datetime.datetime.now" does not work: > > now=datetime.datetime.now > db.define_table('person', > Field('uuid', length=64, default=uuid.uuid4), > Field('modified_on', 'datetime', default=now), > Field('name'), > format='%(name)s') > > db.person.insert(name='Ernie') > db.person.insert(name='Bert') > > > db(db.person).select() > >>> ValueError: invalid literal for int() with base 10: '<built' > > Umm,... > > db.executesql(db(db.person)._select()) > >>> [(1, > u'b35cc052-3800-42a9-b7eb-bb9bc8ada271', > u'<built-in method now of type object at 0x37c520>', > u'Ernie'), > (2, > u'003ab438-f3aa-4474-8c24-b07d85406930', > u'<built-in method now of type object at 0x37c520>', > u'Bert')] > > (only works with Sqlite - MySQL would throw an error earlier) > > > I think this check in BaseAdapter.represent (dal.py) is the culprit: > > def represent(self, obj, fieldtype): > if type(obj) in (types.LambdaType, types.FunctionType): > obj = obj() > > > print type(datetime.datetime.now) in (types.LambdaType, > types.FunctionType) > >>> False > > > This version lets you use any callable for generating "dynamic" > default values (plus it's 3-4 times faster): > > def represent(self, obj, fieldtype): > if callable(obj): > obj = obj() > > > I hope this doesn't cause any side effects - at least I could not find > any (at this late/early hour)... > > Thanks > -- Hilsen Ole Martin Mob: 95227471