Я пишу бота, который слушает потоки и уведомляет своих подписчиков о публикациях. Я работаю с модулем shelve
, который дает мне то, что мне кажется случайными ошибками (обычно они не возникают, но иногда при запуске бота они появляются, и бот больше не может запускаться, пока я не уберу свой файлы базы данных). Это означает, что некоторые сообщения, которые уже были отправлены подписчикам, будут отправлены повторно из-за потери данных.
Возникают две ошибки:
EOFError: Ran out of input
и
pickle.UnpicklingError: pickle data was truncated
Мне удалось (я считаю) определить причину ошибки EOFError, которая возникает, когда бот прерывается (например, KeyboardInterrupt) во время операций ввода-вывода. Эта ошибка не так важна, так как она не будет возникать часто при использовании в реальном мире, но когда это происходит, я все равно вынужден удалить всю базу данных.
Однако ошибка «маринованные данные была усечена» остается для меня загадка, так как я не могу понять, когда это происходит или что именно идет не так. Это также случается чаще. Строка, которая вызывает ошибку: if message.id in self.db['processed_messages']:
. Это первая строка, кроме конструктора, который что-то делает с базой данных.
Я надеюсь на некоторую помощь в устранении этих двух ошибок. Я включил код, который относится к ошибкам на тот случай, если кто-нибудь увидит, что может быть причиной их возникновения.
Код, относящийся к моей проблеме:
import shelve
class Bot():
def __init__(self):
# get data from file or create it if it does not exist
self.db = shelve.open('database')
# init keys if they do not exist (example: first time running the program with empty database):
if 'processed_messages' not in self.db:
self.db['processed_messages'] = []
if 'processed_submissions' not in self.db:
self.db['processed_submissions'] = []
if 'subscribers' not in self.db:
self.db['subscribers'] = []
def handler(self, message):
if message.id in self.db['processed_messages']:
return
self.store_data('processed_messages', message.id)
def store_data(self, key, obj):
""" stores data locally with shelve module """
temp = self.db[key]
temp.append(obj)
self.db[key] = temp
На совершенно другом замечании: если кто-то знает лучший (более элегантный) способ работы со случаем пустой базы данных. Я также хотел бы услышать некоторый вклад, так как текущий подход в конструкторе довольно сомнительный