jdm*_*ino 7 python sqlite datetime
我试图用python + sqlite3替换我对SAS的使用; 我正在尝试将数据从SAS数据集移动到SQLite数据库.我有很多时间字段在python中正确表示为datetime.time对象.由于SQLite是"轻微键入",我正在寻找有关用于在列中存储时间的格式的建议.(我知道我必须编写python适配器等来读取和写入列中的对象.)这些是我需要考虑的功能:
有没有人解决这个问题令他们满意?
有一个通用的方法可以在sqlite表中存储任何可序列化的Python对象.
sqlite3.register_adapter
注册的功能用于转换Python对象为int,长整型,浮点,STR(UTF-8编码),Unicode或缓冲液中.sqlite3.register_converter
注册一个函数用于将文本转换为Python的对象.输入始终是文本,因为在内部,sqlite将所有内容存储为文本.以下是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),) ])
Run Code Online (Sandbox Code Playgroud)
您可以在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()
Run Code Online (Sandbox Code Playgroud)
注意:如果您查看编辑历史记录,您将看到一个更简单的替代方案adapt_timeobj
,convert_timeobj
它将数据存储为a str
而不是a int
.它更简单,但将数据存储int
为更快,更高效的内存.
我非常喜欢@unutbu的答案,但这是一种存储时间戳的简单方法.
RFC 3339是一种非常明确的时间戳格式,便于计算机解析,便于人类阅读.您可以将时间戳存储为字符串.
RFC 3339的一个不错的属性:简单的ASCII排序也按时间顺序排序.
但是你并不真正需要这个规范,因为它非常简单.这是一个例子:
2014-12-24T23:59:59.9999-08:00
Run Code Online (Sandbox Code Playgroud)
这是我的时区圣诞节前一秒钟的最后一小部分,比UTC晚8小时(因此是-08:00
部分).年,月,日,字符串T
,小时,分钟,秒,可选小数秒,时区.
时区也可以Z
指示UTC时间.但是将时间存储在本地时区可能更方便,因此您可以更轻松地阅读它们.
归档时间: |
|
查看次数: |
4650 次 |
最近记录: |