Có một công thức chung để lưu trữ bất kỳ đối tượng Python tuần tự hóa nào trong bảng sqlite.
Đây là những gì các mã nhìn có thể trông như cho datetime.time đối tượng:
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),) ])
Bạn có thể sử dụng sự bất bình đẳng trong SQL, nhưng lưu ý rằng các giá trị được so sánh được trả lại bởi adapt_timeobj
, không các đối tượng datetime.time
. May mắn thay, nếu hàm adapt_timeobj
trả về các số nguyên có thể đặt hàng theo cùng thứ tự với các đối tượng tương ứng datetime.time
(như chúng làm ở trên), thì sự bất bình đẳng trong SQL sẽ hoạt động như mong muốn.
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()
Lưu ý: Nếu bạn nhìn vào lịch sử chỉnh sửa, bạn sẽ thấy một sự thay thế đơn giản hơn cho adapt_timeobj
và convert_timeobj
lưu trữ dữ liệu như một str
thay vì như một int
. Nó đơn giản hơn, nhưng lưu trữ dữ liệu dưới dạng int
nhanh hơn và hiệu quả hơn với bộ nhớ.
Điều đáng nói đến là việc chuyển 'PARSE_DECLTYPES' không bắt buộc trong trường hợp này. – jfs
@JFSebastian: Cũng có thể sử dụng [PARSE_COLNAMES] (https://docs.python.org/2/library/sqlite3.html#sqlite3.PARSE_COLNAMES), nhưng sau đó bạn sẽ cần sử dụng SQL như 'SELECT timecol [ timeobj] ... ' – unutbu
Tôi đã sử dụng micro giây kể từ nửa đêm trong các tình huống khác (không phải python + sqlite). Tôi không thích nó, nhưng nó là hợp lý. Tôi đã không nhận thức được khả năng sử dụng các đối tượng python trong các truy vấn như bạn đã làm trong ví dụ của bạn. Tôi có thể sẽ bắt đầu với đề xuất của bạn. Cảm ơn. – jdmarino