Pyodbc 不返回精确的日期时间数据

Pyodbc not returning precise datetime data

我在 Python 3.4.3 中使用 pyodbc 从 Microsoft Access 数据库 (.mdb) 读取数据。我用来提取时间戳的查询几乎可以正常工作 - 我得到了正确的日期和 hour/minute/seconds 数据,但数据库包含的时间精确到百分之一秒。我的时间戳似乎被截断了。有谁知道我怎样才能得到被遗漏的几分之一秒?

代码

t = cursor.execute('SELECT Time FROM ConditionData')

for record in t:
    print(record)

输出:

(datetime.datetime(2013, 7, 27, 8, 24, 54), )
(datetime.datetime(2013, 7, 27, 8, 27, 48), )
(datetime.datetime(2013, 7, 27, 8, 28, 1), )
(datetime.datetime(2013, 7, 27, 8, 29, 29), )
(datetime.datetime(2013, 7, 27, 8, 32, 44), )

实际时间戳(未截断的秒数):

7/27/2013 8:24:54.27
7/27/2013 8:27:48.95
7/27/2013 8:28:01.97
7/27/2013 8:29:29.12
7/27/2013 8:32:44.40

Access 中的 Date/Time 列标称分辨率为一秒,Access ODBC 驱动程序在从其内部表示形式(Double)转换 Date/Time 值时将丢弃小数秒。因此,例如,如果我们在 SQL 服务器 table

datetime 列中有以下值
2014-08-12 01:02:03.670

然后我们在 Access

中对链接 table 的 ODBC 执行以下查询
import pyodbc

connStr = (
    r"Driver={Microsoft Access Driver (*.mdb, *.accdb)};"
    r"DBQ=C:\Users\Public\Database1.accdb;"
    )
cnxn = pyodbc.connect(connStr)
crsr = cnxn.cursor()

sql = """\
SELECT [Time] FROM ConditionData WHERE ID=1
"""
crsr.execute(sql)
row = crsr.fetchone()
mydatetime = row[0]

print(repr(mydatetime))
print(mydatetime)

crsr.close()
cnxn.close()

我们看到了

datetime.datetime(2014, 8, 12, 1, 2, 3)
2014-08-12 01:02:03

但是,如果我们调整查询并使用 CDbl() 函数来 return 基础 Double 值,那么我们可以将其转换为 datetime 并像这样保留小数秒:

from datetime import datetime, timedelta
import math
import pyodbc

def VT_DATE_double_to_datetime(dbl):
    # math.modf() returns (<fractional_part>, <integer_part>)
    day_parts = math.modf(dbl)
    return (
        datetime(1899, 12, 30) +
        timedelta(days=day_parts[1]) +
        timedelta(seconds=abs(day_parts[0]) * 86400)
        )


connStr = (
    r"Driver={Microsoft Access Driver (*.mdb, *.accdb)};"
    r"DBQ=C:\Users\Public\Database1.accdb;"
    )
cnxn = pyodbc.connect(connStr)
crsr = cnxn.cursor()

sql = """\
SELECT CDbl([Time]) AS ddbl FROM ConditionData WHERE ID=1
"""
crsr.execute(sql)
row = crsr.fetchone()
mydatetime = VT_DATE_double_to_datetime(row[0])

print(repr(mydatetime))
print(mydatetime)

crsr.close()
cnxn.close()

这给了我们

datetime.datetime(2014, 8, 12, 1, 2, 3, 670000)
2014-08-12 01:02:03.670000