如果您在sqlite3.connect 中设置detect_types=sqlite3.PARSE_DECLTYPES,
然后连接将尝试将 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 对象。