我正在尝试用
python sqlite3替换我对SAS的使用;我正在尝试将数据从SAS数据集移动到sqlite数据库.我有很多时间字段在python中正确表示为datetime.time对象.由于sqlite是“轻微键入”,我正在寻找有关用于在列中存储时间的格式的建议. (我知道我必须编写python适配器等来读取和写入列中的对象.)这些是我需要考虑的功能:
> sqlite能够处理查询中的列. (例如,我可以选择两次之间出现的行吗?)
>场地的大小. (我的表通常是数亿行.)
>人类可读性. (我正在考虑将时间存储为整数:自午夜以来的微秒.但这会让数据更加难以理解.)
有没有人解决这个问题让他们满意?
在sqlite表中存储任何可序列化的
Python对象的一般方法.
>使用sqlite3.register_adapter
注册转换功能
Python对象为int,long,float,str(UTF-8编码),unicode或缓冲区.
>使用sqlite3.register_converter
注册功能
将文本转换为Python对象.输入始终是文本,因为internally,sqlite stores everything as text.
以下是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,60*10**6) second,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,)] cur.execute("select timecol from test where timecol < ?",[DT.time(8,0)]) print(cur.fetchall()) # [(datetime.time(1,(datetime.time(5,)] con.commit() cur.close() con.close()
注意:如果查看编辑历史记录,您将看到adapt_timeobj和convert_timeobj的更简单的替代方法,它将数据存储为str而不是int.它更简单,但将数据存储为int更快,内存效率更高.