Datetime fields with microsecond shows as None
MySQL database connector for Python programming
Brought to you by:
adustman
When SELECT datatime field which contained microseconds from DB(MariaDB 5.5 and MySQL 5.6). Result can not be converted to datetime.datetime
and data in that field shows as None
. I use MariaDB 5.5.27.
For example:
Make table in DB and fill its
import MySQLdb db=MySQLdb.connect(host="localhost",user="test",passwd="test",db="test") c=db.cursor() c.execure("""DROP TABLE IF EXISTS `t1`""") c.execure("""CREATE TABLE `t1` ( `id` int(11) `date` datatime(6) NOT NULL, PRIMARY KEY (`id`), ) ENGINE=InnoDB DEFAULT CHARSET=utf8""") c.execure("""INSERT INTO t1 VALUES(1,now(6)), VALUES(2,NOW(6)), VALUES(3,NOW(6))""")
Now we can get data.
c.execute("""SELECT * FROM t1""") r = c.fetchall() print r OUT: ((1L, None), (2L, None), (3L, None))
After patch:
c.execute("""SELECT * FROM t1""") r = c.fetchall() print r OUT: ((1L, datetime.datetime(2012, 10, 3, 10, 56, 47, 800462)), (2L, datetime.datetime(2012, 10, 3, 10, 56, 47, 800462)), (3L, datetime.datetime(2012, 10, 3, 10, 56, 47, 800462)))
It's not obvious what version of MySQLdb you tested against. Can you test against 1.2.4b2? I believe the issue is fixed there.
I have tried in 1.2.4b4, result tuple have None if DateTime field contained microsecond.
Bug in DateTime_or_None() on times.py when func try to return value it can't split microsecond from time
return datetime(*[ int(x) for x in d.split('-')+t.split(':') ])
The example works for the new versions of MySQLdb, but DateTime_Or_None() still parses datetimes with microseconds incorrectly, which leads to problems for clients using it directly (see i.e. https://code.djangoproject.com/ticket/19716). If it is possible, please make changes to DateTime_Or_None().
Last edit: Zmicier Zaleznicenka 2013-03-28
Also, if talking about these ms issues, while Time_Or_None() parses microseconds, rounding errors may appear. Instead, I suggest to use string methods.
This happens now:
~~~~~
Yep, and this problem exist.
May be I can provide more simply way and without math module.
Math module is used now and causes rounding errors. In my post I suggest using string method ljust instead of math.modf. Ljust is simpler and faster (i believe) than rounding the way you propose.
Agree, there is no need in float here. Below is one of the ways to fix the problem:
New patch for solve this problem. Without float numbers.
I just ran into this problem while using twisted.enterprise.adbapi. A simple query of datetime objects returned a None object an all records. The patch here did not fix the problem as it was in the DateTime_or_None method which is not modified.
I guess its already fixed in the next version, but I have posted this just in case. Again its a problem of handling the milliseconds. I made a slight change to this method, adding an if statement after the split and it seems to work.
I think the string replace is not too costly and everything else is the same.
I apologise, I have limited expertise with Python and its tools, so due to my ignorance I am just posting the code change, not the patch.
Please can you provide dataset sample for testing.
Try get sources of MySQLdb from https://github.com/farcepest/MySQLdb1
I have pushed changes to github repo.
Sorry for not replying yesterday, but your email made me notice
something strange and I needed to think about it.
At first glance the basic test outlined below should have picked up the
problem I saw. Essentially I was doing the same, retrieving results with
a datetime object in them and printing them out. I saw the same problem
both before and after the patch. This leaves two possibilities I can see.
wrapper around your library. It might be possible that the two
approaches, literally build a different stack sequence for
processing an execute and different functions are used to convert
the data to a datetime object. (something I find unlikely.)
directly from the link on the bug report and it modified the methods
TimeDelta_or_None and Time_or_None, which were never called in my
test and it left the method DateTime_or_None unchanged. In the
spirit of simplicity I suspect this is the explanation.
I have also noticed that due to these changes, the module is a now a bit
of a patchwork. For example format_TIMEDELTA does not support milliseconds.
I am bogged down with deadlines at the moment, but in the next few days
I will build a test example that I can release using the twisted
library. I have not had time to look at the development branch, but if
you don't already have it I could add a test case for this module. Its
not going to track the stack sequence on the call, but it should help to
keep track of the validity of the methods.
On 05/02/14 13:04, Dmitry T. wrote:
Related
Bugs: #325
Hi,
I'm sorry, this my fail. I was inattentive when read your comment
Please try replace functions code in times.py. Working code below.
This works fine and the ljust protected against badly formatted time
strings, which my suggestion didn't do. I will use this version form now
on. Thanks for your time.
Just one last point, your attached code does not include the
Time_or_None method, which also needs to be changed. In the unlikely
event someone else is effected before the next release, they need to be
aware they need to change all three methods.
Just for completeness, using the same pattern I think that the
Time_or_None method would be