Sqlite3 возвращает строку байтов для даты и времени

У меня есть база данных sqlite3:

import sqlite3
import pandas as pd
from datetime import datetime

batch_size = 10

con = sqlite3.connect(':memory:', detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
cur = con.cursor()

table = """CREATE TABLE my_table(DateCreated DATETIME);"""
cur.execute(table)

DateCreated = [datetime(2020, 12, 1, 1, 1)] * batch_size
x = list(pd.DataFrame({'DateCreated':DateCreated}).to_records(index=False))

query = """INSERT INTO my_table (DateCreated) values (?);"""

cur.executemany(query, x)

Когда я хочу получить дату и время, sqlite3 возвращает строку байтов вместо объекта даты и времени:

cur.execute("SELECT * FROM my_table;")
cur.fetchone()
>> (b'\x00\xf8\xea\x08\xf4qL\x16',)

Что я делаю не так? Я проверил Эта проблема, но это не совсем применимо к моей проблеме. Я также попытался изменить тип данных sqlite с DATETIME на TIMESTAMP, но получил ValueError: not enough values to unpack (expected 2, got 1). Я использую Python 3.8.10.

Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
1
0
30
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Проблема заключается в том, что я использую метод панд .to_record(). Если я уберу этот шаг и предоставлю список кортежи вместо списка пустые записи, тогда база данных правильно вернет дату и время.

import sqlite3
import pandas as pd
from datetime import datetime

batch_size = 10

con = sqlite3.connect(':memory:', detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
cur = con.cursor()

table = """CREATE TABLE my_table(DateCreated DATETIME);"""
cur.execute(table)

DateCreated = [(datetime(2020, 12, 1, 1, 1),)] * batch_size

query = """INSERT INTO my_table (DateCreated) values (?);"""

cur.executemany(query, DateCreated)

cur.execute("SELECT * FROM my_table;")

cur.fetchall()

это по-прежнему возвращает результаты в виде строк, а не объектов даты и времени Python: OP получил неправильный тип столбца для sqlite - должен быть «timestamp». Кроме того, я думаю, что в приведенном примере использование Pandas избыточно, но в случае использования OP это может понадобиться - поэтому мы должны извлечь информацию из фрейма данных как объекты даты и времени.

jsbueno 17.05.2022 21:01

Хороший улов. Ваш ответ более тщательный, чем мой собственный. Спасибо!

FreyGeospatial 17.05.2022 21:24
Ответ принят как подходящий

В вашем фрагменте есть две ошибки: правильный тип данных для столбца sqlite3 — timestamp, а не datetime. Sqlite3, ну, своеобразный, он просто примет что угодно и сохранит все внутри в виде строк - это драйвер Python, который будет по-разному обрабатывать тип столбца «отметка времени» и может напрямую принимать и извлекать объекты даты и времени.

Тем не менее, вызов «df.to_record» также не помогает, поскольку он извлекает дату и время pandas в виде строк. Правильным будет получить значение каждой ячейки pandas и вызвать для него .to_pydatetime().

Итак, если вам нужно конвертировать из другого, не приведенного в примере, dataframe в sqlite, работает такой код:

import sqlite3
import pandas as pd
from datetime import datetime

batch_size = 10

con = sqlite3.connect(':memory:', detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
cur = con.cursor()

table = """CREATE TABLE my_table(DateCreated timestamp)"""
cur.execute(table)

DateCreated = [datetime(2020, 12, 1, 1, 1)] * batch_size
x = [(rec.to_pydatetime(),)  for rec in  pd.DataFrame({'DateCreated':DateCreated})["DateCreated"]]

query = """INSERT INTO my_table (DateCreated) values (?)"""
cur.executemany(query, x)

то, как я написал выражение x = выше, позволит вам выбрать нужные столбцы из вашего фрейма данных и вызывать .to_pydatetime() только в нужных полях.

Если в вашем кадре данных есть 5 других столбцов, а дата и время находятся на 3-м [индекс 2], это работает:

x = [(*rec[0:2], rec[2].to_pydatetime(), *rec[3:])  for _, rec in df.iterrows()]

И, если вы вообще не конвертируете вещи из рабочего процесса pandas, вам не нужно вмешиваться в него, просто создайте объекты даты и времени в виде кортежей и вставьте их:

x = [(datetime.now(),) for i in range(10)] 

Другие вопросы по теме