在 sqlite 表中存储任何可序列化的 Python 对象都有一个通用方法。
以下是 datetime.time 对象的代码外观:
import sqlite3
import datetime as DT
def adapt_timeobj(timeobj):
return ((3600*timeobj.hour + 60*timeobj.minute + timeobj.second)*10**6
+ timeobj.microsecond)
def convert_timeobj(val):
val = int(val)
hour, val = divmod(val, 3600*10**6)
minute, val = divmod(val, 60*10**6)
second, val = divmod(val, 10**6)
microsecond = int(val)
return DT.time(hour, minute, second, microsecond)
# Converts DT.time to TEXT when inserting
sqlite3.register_adapter(DT.time, adapt_timeobj)
# Converts TEXT to DT.time when selecting
sqlite3.register_converter("timeobj", convert_timeobj)
con = sqlite3.connect(":memory:", detect_types=sqlite3.PARSE_DECLTYPES)
cur = con.cursor()
# declare timecol to be of type timeobj
cur.execute("create table test (timecol timeobj)")
cur.executemany("insert into test (timecol) values (?)",
[(DT.time(1,2,3,4), ), (DT.time(5,6,7,8),) ])
您可以在 SQL 中使用不等式,但请注意,要比较的值是 adapt_timeobj 返回的值,不是 datetime.time 对象。幸运的是,如果adapt_timeobj 函数返回的整数可以按照与对应的datetime.time 对象相同的顺序进行排序(如上所述),那么 SQL 中的不等式将按需要工作。
cur.execute("select timecol from test where timecol < ?",
[DT.time(4,5,6)])
print(cur.fetchall())
# [(datetime.time(1, 2, 3, 4),)]
cur.execute("select timecol from test where timecol < ?",
[DT.time(8,0,0)])
print(cur.fetchall())
# [(datetime.time(1, 2, 3, 4),), (datetime.time(5, 6, 7, 8),)]
con.commit()
cur.close()
con.close()
注意:如果您查看编辑历史记录,您会看到adapt_timeobj 和convert_timeobj 的更简单替代方案,它将数据存储为str,而不是int。它更简单,但将数据存储为int 更快且内存效率更高。