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
我在 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