Commits

Mike Bayer  committed f5e6e5d

- applied the "reverse" of r4877 from trunk; correct microsecond behavior is available in 0.4 if you turn off "__legacy_microseconds__" [ticket:1090]

  • Participants
  • Parent commits 4c4fcb9
  • Branches rel_0_4

Comments (0)

Files changed (3)

       that row request (so BufferedColumnRow is still needed, 
       but less so). [ticket:1062]
 
+- sqlite
+    - SQLite supports a "forwards compatible" mode for its
+      DateTime and Time types, regarding the representation of
+      microseconds.  When the mode is enabled, microseconds 
+      are represented as fractional seconds in string format.  
+      This makes SQLA's SQLite date type compatible with datetimes 
+      that were saved directly using Pysqlite (which just calls 
+      str()).  This mode is the default in 0.5, where the 
+      same selector flag exists with the reverse default value.
+
+      To get the new behavior globally:
+
+         from sqlalchemy.databases.sqlite import DateTimeMixin
+         DateTimeMixin.__legacy_microseconds__ = False
+
+      To get the behavior on individual DateTime types:
+
+          t = sqlite.SLDateTime()
+          t.__legacy_microseconds__ = False
+
+      Then use "t" as the type on the Column.
+
+      [ticket:1090]
+
 
 0.4.6
 =====

File lib/sqlalchemy/databases/sqlite.py

 
 class DateTimeMixin(object):
     __format__ = "%Y-%m-%d %H:%M:%S"
-
+    __legacy_microseconds__ = True
+    
     def bind_processor(self, dialect):
         def process(value):
             if isinstance(value, basestring):
                 return value
             elif value is not None:
                 if self.__microsecond__ and getattr(value, 'microsecond', None) is not None:
-                    return value.strftime(self.__format__ + "." + str(value.microsecond))
+                    if self.__legacy_microseconds__:
+                        return value.strftime(self.__format__ + '.' + str(value.microsecond))
+                    else:
+                        return value.strftime(self.__format__ + ('.%06d' % value.microsecond))
                 else:
                     return value.strftime(self.__format__)
             else:
             return None
         try:
             (value, microsecond) = value.split('.')
-            microsecond = int(microsecond)
+            if self.__legacy_microseconds__:
+                microsecond = int(microsecond)
+            else:
+                microsecond = int((microsecond + '000000')[0:6])
         except ValueError:
             microsecond = 0
         return time.strptime(value, self.__format__)[0:6] + (microsecond,)

File test/dialect/sqlite.py

 
         finally:
             meta.drop_all()
+    
+    def test_time_microseconds(self):
+        dt = datetime.datetime(2008, 6, 27, 12, 0, 0, 125)  # 125 usec
 
+        self.assertEquals(str(dt), '2008-06-27 12:00:00.000125')
+        sldt = sqlite.SLDateTime()
+        bp = sldt.bind_processor(None)
+        self.assertEquals(bp(dt), '2008-06-27 12:00:00.125')
+
+        rp = sldt.result_processor(None)
+        self.assertEquals(rp(bp(dt)), dt)
+
+        sldt.__legacy_microseconds__ = False
+        self.assertEquals(bp(dt), '2008-06-27 12:00:00.000125')
+        self.assertEquals(rp(bp(dt)), dt)
+        
+        
     @testing.uses_deprecated('Using String type with no length')
     def test_type_reflection(self):
         # (ask_for, roundtripped_as_if_different)