首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将python datetime.time存储在sqlite3列中的最佳方法?

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

Stack Overflow用户
提问于 2014-12-24 18:21:22
回答 2查看 6.5K关注 0票数 10

我试图用python +sqlite3取代我对SAS的使用;我试图将数据从SAS数据集中移到SQLite数据库。我有许多在python中正确表示为datetime.time对象的时间域。由于SQLite是“轻描淡写的”,我正在寻找关于在列中存储时间的格式的建议。(我知道我必须编写python适配器等,才能将对象读写到列中。)以下是我需要考虑的特性:

  • SQLite在查询中处理列的能力。(例如,我能选择两次之间发生的行吗?)
  • 场地的大小。(我的桌子通常有数亿行。)
  • 人类的可读性(我正在考虑将时间存储为整数:午夜以来的微秒。但这使得观察数据变得更加困难。)

有人满意地解决了这个问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-24 18:53:05

有一个通用的方法可以将任何可序列化的Python对象存储在sqlite表中。

下面是datetime.time对象的代码外观:

代码语言:javascript
运行
复制
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中的不等式将按需要工作。

代码语言:javascript
运行
复制
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_timeobjconvert_timeobj的一个更简单的替代方案,即将数据存储为str而不是int。它更简单,但将数据存储为int更快,内存效率更高。

票数 9
EN

Stack Overflow用户

发布于 2014-12-24 19:18:55

我非常喜欢回答@unutbu,但是这里有一个简单的存储时间戳的方法。

RFC 3339是一种非常明确的时间戳格式,便于计算机解析和人类阅读。您可以将时间戳存储为字符串。

RFC 3339的一个很好的特性是:一个简单的ASCII排序也按时间顺序排序。

但是你并不需要这个规范,因为它太简单了。下面是一个例子:

代码语言:javascript
运行
复制
2014-12-24T23:59:59.9999-08:00

这是圣诞节前的最后一秒钟,在我的时区,比UTC落后8小时(因此是-08:00部分)。年份、月份、日期、字符串T、小时、分钟、秒、可选小数秒、时区。

时区也可以是Z,它指示UTC时间。但是,将时间存储在当地时区可能更方便,这样您就可以更容易地阅读它们。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27640857

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档