[SQL-CVS] r4678 - in SQLObject/trunk: docs sqlobject sqlobject/tests
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
From: <sub...@co...> - 2013-12-08 16:38:25
|
Author: phd Date: Sun Dec 8 08:59:20 2013 New Revision: 4678 Log: DateTimeCol and TimeCol preserve microseconds Modified: SQLObject/trunk/docs/News.txt SQLObject/trunk/docs/TODO.txt SQLObject/trunk/sqlobject/col.py SQLObject/trunk/sqlobject/converters.py SQLObject/trunk/sqlobject/tests/test_converters.py SQLObject/trunk/sqlobject/tests/test_datetime.py Modified: SQLObject/trunk/docs/News.txt ============================================================================== --- SQLObject/trunk/docs/News.txt Sun Dec 8 08:57:03 2013 (r4677) +++ SQLObject/trunk/docs/News.txt Sun Dec 8 08:59:20 2013 (r4678) @@ -16,6 +16,10 @@ * Python 2.4 is no longer supported. The minimal supported version is Python 2.5. +* DateTimeCol and TimeCol preserve microseconds. The feature requires + Python 2.6+ because in Python 2.5 datetime.strptime doesn't support + '%f' format. + SQLObject 1.5.1 =============== Modified: SQLObject/trunk/docs/TODO.txt ============================================================================== --- SQLObject/trunk/docs/TODO.txt Sun Dec 8 08:57:03 2013 (r4677) +++ SQLObject/trunk/docs/TODO.txt Sun Dec 8 08:59:20 2013 (r4678) @@ -46,7 +46,8 @@ * Cache columns in sqlmeta.getColumns(); reset the cache on add/del Column/Join. * Stop supporting Python 2.5: remove import sets; use ``with lock``; - make ConnectionHub a context manager instead of .doInTransaction(). + make ConnectionHub a context manager instead of .doInTransaction(); + replace time.strptime with datetime.strptime. * Create JSONCol. Modified: SQLObject/trunk/sqlobject/col.py ============================================================================== --- SQLObject/trunk/sqlobject/col.py Sun Dec 8 08:57:03 2013 (r4677) +++ SQLObject/trunk/sqlobject/col.py Sun Dec 8 08:59:20 2013 (r4678) @@ -20,7 +20,9 @@ from array import array from itertools import count -import re, time +import re +import sys +import time try: import cPickle as pickle except ImportError: @@ -1098,11 +1100,23 @@ else: return datetime.time(value.hour, value.minute, int(value.second)) try: - stime = time.strptime(value, self.format) + if self.format.find(".%f") >= 0: + if '.' in value: + _value = value.split('.') + microseconds = _value[-1] + if len(microseconds) > 6: + _value[-1] = microseconds[:6] + value = '.'.join(_value) + else: + value += '.0' + if sys.version_info[:3] < (2, 6, 0): # datetime.strptime in python2.5 doesn't support '%f' format + stime = time.strptime(value, self.format) + return datetime.datetime(*stime[:6]) + else: + return datetime.datetime.strptime(value, self.format) except: raise validators.Invalid("expected a date/time string of the '%s' format in the DateTimeCol '%s', got %s %r instead" % \ (self.format, self.name, type(value), value), value, state) - return datetime.datetime(*stime[:6]) def from_python(self, value, state): if value is None: @@ -1129,11 +1143,25 @@ elif isinstance(value, datetime.time): return DateTime.Time(value.hour, value.minute, value.second) try: - stime = time.strptime(value, self.format) + if self.format.find(".%f") >= 0: + if '.' in value: + _value = value.split('.') + microseconds = _value[-1] + if len(microseconds) > 6: + _value[-1] = microseconds[:6] + value = '.'.join(_value) + else: + value += '.0' + if sys.version_info[:3] < (2, 6, 0): # datetime.strptime in python2.5 doesn't support '%f' format + stime = time.strptime(value, self.format) + return DateTime.mktime(stime) + else: + value = datetime.datetime.strptime(value, self.format) + return DateTime.DateTime(value.year, value.month, value.day, + value.hour, value.minute, value.second) except: raise validators.Invalid("expected a date/time string of the '%s' format in the DateTimeCol '%s', got %s %r instead" % \ (self.format, self.name, type(value), value), value, state) - return DateTime.mktime(stime) def from_python(self, value, state): if value is None: @@ -1146,7 +1174,7 @@ (self.name, type(value), value), value, state) class SODateTimeCol(SOCol): - datetimeFormat = '%Y-%m-%d %H:%M:%S' + datetimeFormat = '%Y-%m-%d %H:%M:%S.%f' def __init__(self, **kw): datetimeFormat = kw.pop('datetimeFormat', None) @@ -1277,7 +1305,7 @@ from_python = to_python class SOTimeCol(SOCol): - timeFormat = '%H:%M:%S' + timeFormat = '%H:%M:%S.%f' def __init__(self, **kw): timeFormat = kw.pop('timeFormat', None) Modified: SQLObject/trunk/sqlobject/converters.py ============================================================================== --- SQLObject/trunk/sqlobject/converters.py Sun Dec 8 08:57:03 2013 (r4677) +++ SQLObject/trunk/sqlobject/converters.py Sun Dec 8 08:59:20 2013 (r4678) @@ -7,16 +7,11 @@ try: - import mx.DateTime.ISO - origISOStr = mx.DateTime.ISO.strGMT from mx.DateTime import DateTimeType, DateTimeDeltaType except ImportError: try: - import DateTime.ISO - origISOStr = DateTime.ISO.strGMT from DateTime import DateTimeType, DateTimeDeltaType except ImportError: - origISOStr = None DateTimeType = None DateTimeDeltaType = None @@ -41,17 +36,6 @@ ('\t', '\\t'), ] -def isoStr(val): - """ - Gets rid of time zone information - (@@: should we convert to GMT?) - """ - val = origISOStr(val) - if val.find('+') == -1: - return val - else: - return val[:val.find('+')] - class ConverterRegistry: def __init__(self): @@ -133,12 +117,12 @@ if DateTimeType: def DateTimeConverter(value, db): - return "'%s'" % isoStr(value) + return "'%s'" % value.strftime("%Y-%m-%d %H:%M:%S.%s") registerConverter(DateTimeType, DateTimeConverter) def TimeConverter(value, db): - return "'%s'" % value.strftime("%T") + return "'%s'" % value.strftime("%H:%M:%S") registerConverter(DateTimeDeltaType, TimeConverter) @@ -167,9 +151,9 @@ registerConverter(time.struct_time, StructTimeConverter) def DateTimeConverter(value, db): - return "'%04d-%02d-%02d %02d:%02d:%02d'" % ( + return "'%04d-%02d-%02d %02d:%02d:%02d.%d'" % ( value.year, value.month, value.day, - value.hour, value.minute, value.second) + value.hour, value.minute, value.second, value.microsecond) registerConverter(datetime.datetime, DateTimeConverter) @@ -179,7 +163,7 @@ registerConverter(datetime.date, DateConverter) def TimeConverter(value, db): - return "'%02d:%02d:%02d'" % (value.hour, value.minute, value.second) + return "'%02d:%02d:%02d.%d'" % (value.hour, value.minute, value.second, value.microsecond) registerConverter(datetime.time, TimeConverter) Modified: SQLObject/trunk/sqlobject/tests/test_converters.py ============================================================================== --- SQLObject/trunk/sqlobject/tests/test_converters.py Sun Dec 8 08:57:03 2013 (r4677) +++ SQLObject/trunk/sqlobject/tests/test_converters.py Sun Dec 8 08:59:20 2013 (r4678) @@ -88,11 +88,11 @@ def test_datetime(): from datetime import datetime, date, time - assert sqlrepr(datetime(2005, 7, 14, 13, 31, 2)) == "'2005-07-14 13:31:02'" + assert sqlrepr(datetime(2005, 7, 14, 13, 31, 2)) == "'2005-07-14 13:31:02.0'" assert sqlrepr(date(2005, 7, 14)) == "'2005-07-14'" - assert sqlrepr(time(13, 31, 2)) == "'13:31:02'" + assert sqlrepr(time(13, 31, 2)) == "'13:31:02.0'" # now dates before 1900 - assert sqlrepr(datetime(1428, 7, 14, 13, 31, 2)) == "'1428-07-14 13:31:02'" + assert sqlrepr(datetime(1428, 7, 14, 13, 31, 2)) == "'1428-07-14 13:31:02.0'" assert sqlrepr(date(1428, 7, 14)) == "'1428-07-14'" def test_instance(): Modified: SQLObject/trunk/sqlobject/tests/test_datetime.py ============================================================================== --- SQLObject/trunk/sqlobject/tests/test_datetime.py Sun Dec 8 08:57:03 2013 (r4677) +++ SQLObject/trunk/sqlobject/tests/test_datetime.py Sun Dec 8 08:59:20 2013 (r4678) @@ -25,7 +25,8 @@ assert dt1.col1.day == _now.day assert dt1.col1.hour == _now.hour assert dt1.col1.minute == _now.minute - assert dt1.col1.second == int(_now.second) + assert dt1.col1.second == _now.second + assert dt1.col1.microsecond == _now.microsecond assert isinstance(dt1.col2, date) assert not isinstance(dt1.col2, datetime) @@ -36,7 +37,8 @@ assert isinstance(dt1.col3, time) assert dt1.col3.hour == _now.hour assert dt1.col3.minute == _now.minute - assert dt1.col3.second == int(_now.second) + assert dt1.col3.second == _now.second + assert dt1.col3.microsecond == _now.microsecond if mxdatetime_available: col.default_datetime_implementation = MXDATETIME_IMPLEMENTATION @@ -47,7 +49,7 @@ if connection.dbName == "sqlite": if connection.using_sqlite2: # mxDateTime sends and PySQLite2 returns full date/time for dates - dateFormat = "%Y-%m-%d %H:%M:%S" + dateFormat = "%Y-%m-%d %H:%M:%S.%f" class DateTime2(SQLObject): col1 = DateTimeCol() @@ -57,7 +59,7 @@ def test_mxDateTime(): setupClass(DateTime2) _now = now() - dt2 = DateTime2(col1=_now, col2=_now, col3=Time(_now.hour, _now.minute, int(_now.second))) + dt2 = DateTime2(col1=_now, col2=_now, col3=Time(_now.hour, _now.minute, _now.second)) assert isinstance(dt2.col1, col.DateTimeType) assert dt2.col1.year == _now.year |