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

Reply via email to