both. I think the code fix you propose should be included in trunk. At the same time, I'd prefer to have now() in the book.
On Jan 26, 9:32 am, Vinicius Assef <vinicius...@gmail.com> wrote: > Massimo, > will you fix the book or web2py source code? > > On Wed, Jan 26, 2011 at 12:49 PM, Massimo Di Pierro > > > > > > > > <massimo.dipie...@gmail.com> wrote: > > Good catch. I will fix this asap. > > > On Jan 25, 6:36 pm, 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