SQLite日期存储和转换

时间:2010-11-25 01:04:19

标签: python sqlite

我在使用Python和SQLite进行日期存储/检索时遇到了设计问题。

据我所知,SQLite日期列将日期存储为ISO格式的文本 (即'2010-05-25')。所以,当我显示英国约会时(例如,在网页上)我 使用

转换日期
datetime.datetime.strptime(mydate,'%Y-%m-%d').strftime('%d/%m/%Y')

然而,当谈到将数据写回到表时,SQLite非常 原谅并且非常乐意将'25/06/2003'存储在日期字段中,但是这样

是不理想的
  • 我可以在同一时间内混合使用日期格式 柱,

  • SQLite的日期函数仅适用于ISO格式。

因此我需要先将日期字符串转换回ISO格式 提交,但后来我需要一个检查数据的通用函数 写入所有日期字段,并在必要时转换为ISO。听起来像是一个 对我来说有点乏味,但也许这是不可避免的。

有更简单的解决方案吗?将日期字段更改为a会更容易吗? 整个表格中包含10个字符的字段和商店'dd/mm/yyyy'?这样没有 从表中读取或写入时需要转换,我可以使用 datetime()函数,如果我需要执行任何日期算术。

其他开发者如何克服这个问题?任何帮助,将不胜感激。 为了记录,我使用SQLite3和Python 3.1。

2 个答案:

答案 0 :(得分:14)

如果您在detect_types=sqlite3.PARSE_DECLTYPES中设置sqlite3.connect, 然后连接将尝试将sqlite数据类型转换为Python数据类型 当您从数据库中提取数据时。

这是一件非常好的事情,因为使用datetime对象比使用它更好 随后类似于日期的字符串,然后您必须解析它们 datetime.datetime.strptimedateutil.parser.parse

不幸的是,使用detect_types并不能阻止接受的sqlite 字符串作为DATE数据,但在尝试时会出现错误 从数据库中提取数据(如果以YYYY-MM-DD以外的其他格式插入) 因为连接无法将其转换为datetime.date对象:

conn=sqlite3.connect(':memory:',detect_types=sqlite3.PARSE_DECLTYPES) 
cur=conn.cursor()
cur.execute('CREATE TABLE foo(bar DATE)')
# Unfortunately, this is still accepted by sqlite
cur.execute("INSERT INTO foo(bar) VALUES (?)",('25/06/2003',))

# But you won't be able to draw the data out later because parsing will fail
try:
    cur.execute("SELECT * FROM foo")
except ValueError as err:
    print(err)
    # invalid literal for int() with base 10: '25/06/2003'
    conn.rollback()

但至少错误会提醒您已插入的事实 当你真的应该插入datetime.date对象时,DATE的字符串:

cur.execute("INSERT INTO foo(bar) VALUES (?)",(datetime.date(2003,6,25),))
cur.execute("SELECT ALL * FROM foo")
data=cur.fetchall()
data=zip(*data)[0]
print(data)
# (datetime.date(2003, 6, 25),)

只要您使用YYYY-MM-DD格式,您也可以将字符串作为DATE数据插入。请注意,虽然您插入了一个字符串,但它会以datetime.date对象的形式返回:

cur.execute("INSERT INTO foo(bar) VALUES (?)",('2003-06-25',))
cur.execute("SELECT ALL * FROM foo")
data=cur.fetchall()
data=zip(*data)[0]
print(data)
# (datetime.date(2003, 6, 25), datetime.date(2003, 6, 25))

因此,如果您仅对datetime.date字段中插入DATE个对象进行处分,那么在以后绘制数据时您就不会遇到任何问题。

如果您的用户正在以各种格式输入日期数据,请查看dateutil.parser.parse。它可以帮助您将这些不同的字符串转换为datetime.datetime个对象。

答案 1 :(得分:5)

请注意,SQLite本身没有本机日期/时间类型。正如@unutbu回答的那样,你可以让pysqlite / sqlite3模块尝试猜测(并注意它确实是猜测)哪些列/值是日期/时间。 SQL表达式很容易混淆它。

SQLite确实有各种日期时间函数,可以使用各种字符串,unixepoch和julian格式的数字,并且可以进行转换。请参阅文档:

http://www.sqlite.org/lang_datefunc.html

您可能会发现让SQLite更方便地完成您需要的日期/时间工作,而不是将值导入Python并使用Python库来完成。请注意,您可以在SQL表定义中放置约束,例如要求存在字符串值,是一定长度等。