加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

在sqlite3列中存储python datetime.time的最佳方法?

发布时间:2020-12-12 19:07:14 所属栏目:百科 来源:网络整理
导读:我正在尝试用 python sqlite3替换我对SAS的使用;我正在尝试将数据从SAS数据集移动到SQLite数据库.我有很多时间字段在python中正确表示为datetime.time对象.由于SQLite是“轻微键入”,我正在寻找有关用于在列中存储时间的格式的建议. (我知道我必须编写python
我正在尝试用 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更快,内存效率更高.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读