Если вы установите detect_types=sqlite3.PARSE_DECLTYPES
в sqlite3.connect
,
тогда соединение попытается преобразовать типы данных sqlite в типы данных Python
когда вы выводите данные из базы данных.
Это очень хорошая вещь, так как гораздо лучше работать с объектами datetime, чем
случайные строки, похожие на даты, которые вы затем должны проанализировать
datetime.datetime.strptime
или dateutil.parser.parse
.
К сожалению, использование detect_types
не останавливает sqlite от принятия
строки как данные DATE, но вы получите сообщение об ошибке при попытке
вытянуть данные из базы данных (если они были вставлены в каком-либо формате, отличном от YYYY-MM-DD)
потому что соединение не сможет преобразовать его в объект datetime.date:
conn=sqlite3.connect(':memory:',detect_types=sqlite3.PARSE_DECLTYPES)
cur=conn.cursor()
cur.execute('CREATE TABLE foo(bar DATE)')
# Unfortunately, this is still accepted by sqlite
cur.execute("INSERT INTO foo(bar) VALUES (?)",('25/06/2003',))
# But you won't be able to draw the data out later because parsing will fail
try:
cur.execute("SELECT * FROM foo")
except ValueError as err:
print(err)
# invalid literal for int() with base 10: '25/06/2003'
conn.rollback()
Но, по крайней мере, ошибка предупредит вас о том, что вы вставили
строка для DATE, когда вам действительно нужно вставлять объекты datetime.date:
cur.execute("INSERT INTO foo(bar) VALUES (?)",(datetime.date(2003,6,25),))
cur.execute("SELECT ALL * FROM foo")
data=cur.fetchall()
data=zip(*data)[0]
print(data)
# (datetime.date(2003, 6, 25),)
Вы также можете вставлять строки в виде данных DATE, если вы используете формат ГГГГ-ММ-ДД. Обратите внимание, что хотя вы вставили строку, она возвращается как объект datetime.date
:
cur.execute("INSERT INTO foo(bar) VALUES (?)",('2003-06-25',))
cur.execute("SELECT ALL * FROM foo")
data=cur.fetchall()
data=zip(*data)[0]
print(data)
# (datetime.date(2003, 6, 25), datetime.date(2003, 6, 25))
Так что, если вы дисциплинированно вставляете только datetime.date
объекты в поле DATE
, у вас не возникнет проблем при выводе данных позже.
Если ваши пользователи вводят данные даты в различных форматах, проверьте dateutil.parser.parse . Это может помочь вам преобразовать эти различные строки в datetime.datetime
объекты.