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
|