【发布时间】:2010-12-22 05:45:55
【问题描述】:
我正在使用 Python 2.6.4 中的 sqlite3 模块将日期时间存储在 SQLite 数据库中。插入它非常容易,因为 sqlite 会自动将日期转换为字符串。问题是,在读取它时它会以字符串形式返回,但我需要重建原始的 datetime 对象。我该怎么做?
【问题讨论】:
我正在使用 Python 2.6.4 中的 sqlite3 模块将日期时间存储在 SQLite 数据库中。插入它非常容易,因为 sqlite 会自动将日期转换为字符串。问题是,在读取它时它会以字符串形式返回,但我需要重建原始的 datetime 对象。我该怎么做?
【问题讨论】:
事实证明 sqlite3 可以做到这一点,甚至是 documented,有点 - 但很容易错过或误解。
我要做的是:
conn = sqlite3.connect(dbFilePath, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
将我想要的类型放入查询中 - 对于日期时间,它实际上不是“日期时间”,而是“时间戳”:
sql = 'SELECT jobid, startedTime as "[timestamp]" FROM job'
cursor = conn.cursor()
try:
cursor.execute(sql)
return cursor.fetchall()
finally:
cursor.close()
如果我传入“datetime”,它会被默默地忽略,我仍然会得到一个字符串。如果我省略引号也一样。
【讨论】:
"[timestamp]",[timestamp] 被默默忽略,.fetchone 也不会转换类型。多么奇怪的图书馆。
as 关键字
如果你用时间戳类型声明你的列,你就在三叶草中:
>>> db = sqlite3.connect(':memory:', detect_types=sqlite3.PARSE_DECLTYPES)
>>> c = db.cursor()
>>> c.execute('create table foo (bar integer, baz timestamp)')
<sqlite3.Cursor object at 0x40fc50>
>>> c.execute('insert into foo values(?, ?)', (23, datetime.datetime.now()))
<sqlite3.Cursor object at 0x40fc50>
>>> c.execute('select * from foo')
<sqlite3.Cursor object at 0x40fc50>
>>> c.fetchall()
[(23, datetime.datetime(2009, 12, 1, 19, 31, 1, 40113))]
看到了吗? int(对于声明为整数的列)和 datetime(对于声明为时间戳的列)都可以在类型完整的情况下进行往返。
【讨论】:
u'2012-01-01 18:35:24.617954-02:00'这样的时区感知值来说,这似乎失败了
注意:在 Python3 中,我必须将 SQL 更改为:
SELECT jobid, startedTime as "st [timestamp]" FROM job
(我必须明确命名该列。)
【讨论】:
as 关键字。例如,这很好用:SELECT jobid, startedTime "[timestamp]" FROM job