Thanks for the suggestion Massimo. It looks like the GAE code is working properly, at least for inserting the data (see below for details on how I tested this). The truncation for displaying GAE datetime values was happening in the as_list() function in the sql.py file [line 2346], and when I removed that step from my code I could work with information in GAE's datastore with micro-second precision.
However, it took more work to get fractional seconds working for SQLite. Here is a description of the changes I made to the code in sql.py. Truncation of fractional seconds happens during both insertion and reading from the database. To fix insertion, I changed line 409 from this: obj = obj.strftime('%Y-%m-%d %H:%M:%S') to this: if obj.microsecond > 0: obj = obj.strftime('%Y-%m-%d %H:%M:%S') + '.' + str (obj.microsecond).zfill(6) else: obj = obj.strftime('%Y-%m-%d %H:%M:%S') To fix reading from the database, I added these lines after 2302: ms = 0 # default if (len(str(value)) > 19) and (str(value)[19] == '.'): dec = str(value).rfind('.') dec_end = len(str(value)) if 18 < dec < dec_end: ms = int(int(str(value)[dec+1:dec_end]) * pow (10,(7-dec_end+dec)) ) and I changed this line: row[tablename][fieldname] = datetime.datetime(y, m, d, h, mi, s) to be this: row[tablename][fieldname] = datetime.datetime(y, m, d, h, mi, s, ms) If I'm interpreting the sql.py code correctly, this issue probably affects all of the other databases - I didn't change any of the special-case code for datetime support for other types of databases, or for the time data type. And I didn't change the IS_DATETIME() function in validators.py either. Note that these routines could be simplified when operating with python2.6: "New in version 2.6: time and datetime objects support a %f format code which expands to the number of microseconds in the object, zero- padded on the left to six places." (http://docs.python.org/library/ datetime.html) For python2.5, it's possible to use the datetime's microsecond attribute to get the information. Dan For future reference by GAE developers (including myself): Using the GAE development console (http://localhost:8080/_ah/admin/ interactive), I could run a quick set of lines to get the actual values stored in the GAE datastore, which indeed contain the full precision of what I inserted. These are the lines that I used: import datetime as datetime from google.appengine.ext import db class timetest(db.Model): starttime = db.DateTimeProperty() endtime = db.DateTimeProperty() qry = db.Query(timetest) rows = qry.fetch(limit=5) for r in rows: print r.starttime which produced these results, including some fractional seconds: 1970-01-01 00:00:44.400000 1970-01-01 00:00:12.200000 On Jun 29, 6:55 pm, mdipierro <mdipie...@cs.depaul.edu> wrote: > correction. not print statements on GAE but logging statetements. > > On Jun 29, 8:54 pm, mdipierro <mdipie...@cs.depaul.edu> wrote: > > > In gluon/contrib/gql.py web2py does this: > > > if field.type == 'datetime' and value != None and not > > isinstance(value, datetime.datetime): > > (y, m, d) = [int(x) for x in > > str(value)[:10].strip().split('-')] > > time_items = [int(x) for x in > > str(value)[11:].strip().split(':')[:3]] > > if len(time_items) == 3: > > (h, mi, s) = time_items > > else: > > (h, mi, s) = time_items + [0] > > row[tablename][fieldname] = datetime.datetime > > (y,m,d,h,mi,s) > > .... > > else: > > row[tablename][fieldname] = value > > > perhaps you can put some print statements and see what "value" vs what > > it should be. > > > Massimo > > > On Jun 29, 8:36 pm, Dan <danbr...@gmail.com> wrote: > > > > Here is some sample code to produce the behavior I'm trying to > > > describe. Note that in the controller, there are 2 lines commented out > > > because they return an error ("TypeError: unsupported operand type(s) > > > for -: 'str' and 'str'") > > > > db.define_table('timetest', > > > db.Field('starttime','datetime',default=request.now), > > > db.Field('endtime','datetime',default=request.now), > > > ) > > > > def timetest(): > > > form=FORM(TABLE( > > > TR("Start time (Epoch Seconds UTC):",INPUT > > > (_type="text",_name="start_time_es")), > > > TR("End time (Epoch Seconds UTC):",INPUT > > > (_type="text",_name="end_time_es")), > > > TR("",INPUT(_type="submit",_value="Submit")) > > > )) > > > > rowtoinsert = {} > > > if form.accepts(request.vars): > > > response.flash="form accepted input" > > > startdatetime = datetime.datetime.utcfromtimestamp(float > > > (form.vars.start_time_es)) > > > enddatetime = datetime.datetime.utcfromtimestamp(float > > > (form.vars.end_time_es)) > > > # make the database insertion > > > rowtoinsert={ > > > 'starttime':startdatetime, > > > 'endtime':enddatetime, > > > } > > > idinserted = db.timetest.insert(**rowtoinsert) > > > elif form.errors: > > > response.flash="form is invalid" > > > > existing_rows = db(db.timetest.id>0).select().as_list() > > > # for r in existing_rows: > > > # r['time_difference'] = r['endtime'] - r['starttime'] > > > > return dict(form=form, > > > rowtoinsert=rowtoinsert, > > > existing_rows=existing_rows) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "web2py Web Framework" group. To post to this group, send email to web2py@googlegroups.com To unsubscribe from this group, send email to web2py+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/web2py?hl=en -~----------~----~----~----~------~----~------~--~---