我在使用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。
答案 0 :(得分:14)
如果您在detect_types=sqlite3.PARSE_DECLTYPES
中设置sqlite3.connect
,
然后连接将尝试将sqlite数据类型转换为Python数据类型
当您从数据库中提取数据时。
这是一件非常好的事情,因为使用datetime对象比使用它更好
随后类似于日期的字符串,然后您必须解析它们
datetime.datetime.strptime
或dateutil.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表定义中放置约束,例如要求存在字符串值,是一定长度等。