Работа с датой и временем в SQLite

В этом примере рассмотрим, как работать с датами и временем в SQLite и Python. Часто требуется вставлять дату или объект datetime из Python в таблицу SQLite. Также нужно читать данные в формате datetime, сохраненные в SQLite, и конвертировать их в объекты соответствующего типа в Python для использования в программе.

Перед работой с программой нужно убедиться, что у вас есть база данных из прошлых уроков sqlite_python.db.

В этом примере будет использоваться таблица new_developers.

Пример вставки/получения объекта DateTime

Обычно при выполнении запроса на вставку объекта datetime модуль sqlite3 в Python конвертирует его в строковый формат. То же самое происходит при получении данных из таблицы — они возвращаются в строковом формате. Разберем на простом примере.


import sqlite3, datetime

def add_developer(dev_id, name, joining_date):
try:
sqlite_connection = sqlite3.connect('sqlite_python.db')
cursor = sqlite_connection.cursor()
print("Подключен к SQLite")

sqlite_create_table_query = '''CREATE TABLE new_developers (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
joiningDate timestamp);'''

cursor = sqlite_connection.cursor()
cursor.execute(sqlite_create_table_query)

# вставить данные разработчика
sqlite_insert_with_param = """INSERT INTO 'new_developers'
('id', 'name', 'joiningDate')
VALUES (?, ?, ?);"""

data_tuple = (dev_id, name, joining_date)
cursor.execute(sqlite_insert_with_param, data_tuple)
sqlite_connection.commit()
print("Разработчик успешно добавлен \n")

# получить данные разработчика
sqlite_select_query = """SELECT name, joiningDate from new_developers where id = ?"""
cursor.execute(sqlite_select_query, (1,))
records = cursor.fetchall()

for row in records:
developer= row[0]
joining_date = row[1]
print(developer, "присоединился", joining_date)
print("тип даты", type(joining_date))
cursor.close()

except sqlite3.Error as error:
print("Ошибка при работе с SQLite", error)
finally:
if sqlite_connection:
sqlite_connection.close()
print("Соединение с SQLite закрыто")

add_developer(1, 'Mark', datetime.datetime.now())

Вывод:

Подключен к SQLite
Разработчик успешно добавлен 

Mark присоединился 2020-12-28 10:58:48.828803
тип даты <class 'str'>
Соединение с SQLite закрыто

Как можно видеть, в таблицу был вставлен объект даты, но после получения он стал строкой. Однако это не мешает конвертировать результат обратно в объект даты.

Для этого используется detect_types с PARSE_DECLTYPES и PARSE_COLNAMES в качестве аргументов в методе connect модуля sqlite3.

sqlite3.PARSE_DECLTYPES

Эта константа используется как значение параметра detect_types метода connect().

Если использовать этот параметр в методе connect(), то модуль sqlite3 будет парсить тип каждой получаемой колонки.

После парсинга используется словарь конвертации типов для поиска выполнения конкретной функции конвертации.

sqlite3.PARSE_COLNAMES

Эта константа нужна для того же параметра.

При ее использовании интерфейс SQLite сохранит значения имени каждой возвращаемой колонки. После этого можно аналогично использовать словарь для конвертации в нужный тип.

Посмотрим на следующий пример. В нем при считывании объекта datetime из таблицы SQLite нужно получить объединяющий тип — datetime.


import sqlite3, datetime

def add_developer(dev_id, name, joining_date):
try:
sqlite_connection = sqlite3.connect('sqlite_python.db',
detect_types=sqlite3.PARSE_DECLTYPES |
sqlite3.PARSE_COLNAMES)
cursor = sqlite_connection.cursor()
print("Подключен к SQLite")

sqlite_create_table_query = '''CREATE TABLE new_developers2 (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
joiningDate timestamp);'''

cursor = sqlite_connection.cursor()
cursor.execute(sqlite_create_table_query)

# вставить данные разработчика
sqlite_insert_with_param = """INSERT INTO 'new_developers2'
('id', 'name', 'joiningDate')
VALUES (?, ?, ?);"""

data_tuple = (dev_id, name, joining_date)
cursor.execute(sqlite_insert_with_param, data_tuple)
sqlite_connection.commit()
print("Разработчик успешно добавлен \n")

# получить данные разработчика
sqlite_select_query = """SELECT name, joiningDate from new_developers2 where id = ?"""
cursor.execute(sqlite_select_query, (1,))
records = cursor.fetchall()

for row in records:
developer= row[0]
joining_date = row[1]
print(developer, "присоединился", joining_date)
print("тип даты", type(joining_date))
cursor.close()

except sqlite3.Error as error:
print("Ошибка при работе с SQLite", error)
finally:
if sqlite_connection:
sqlite_connection.close()
print("Соединение с SQLite закрыто")

add_developer(1, 'Mark', datetime.datetime.now())

Вывод:

Подключен к SQLite
Разработчик успешно добавлен 

Mark присоединился 2020-12-28 11:11:01.304116
тип даты <class 'datetime.datetime'>
Соединение с SQLite закрыто

В результате вернувшиеся данные из таблицы представлены типом datetime.datetime.

Подписывайтесь на канал в Дзене

Полезный контент для начинающих и опытных программистов в канале Лента Python разработчика — Как успевать больше, делать лучше и не потерять мотивацию.

Обучение Python и Data Science

Профессия Data Scientist

Профессия Data Scientist

11 520 5 760 ₽/мес.
Профессия Python-разработчик

Профессия Python-разработчик

7 820 3 910 ₽/мес.
Профессия Python Fullstack

Профессия Python Fullstack

7 820 3 910 ₽/мес.
Курс Аналитик данных с нуля

Курс Аналитик данных с нуля

6 500 3 900 ₽/мес.

Появились вопросы? Задайте на Яндекс.Кью

У сайта есть сообщество на Кью >> Python Q <<. Там я, эксперты и участники отвечаем на вопросы по python и программированию.