Сохранить отправленное пользователем изображение в БД sqlite3

Я пишу дота для telegram при помощи библиотеки telebot на python. Возникла проблема. Пользователь отправляет боту фотографию, а бот должен сохранить эту фотографию в базе данных sqlite3. Если точнее, то нужно сначала перевести фотографию пользователя в формат blob, а потом сохранить в БД, и сделать это нужно напрямую, чтобы не использовать много ресурсов сервера. Основная проблема возникает при переводе фото в бинарный объект.

def whatToWatch(message):
rkm = telebot.types.ReplyKeyboardMarkup(resize_keyboard=True) # создание клавитатуры
detectiveBtn = telebot.types.KeyboardButton("Детективы?") # Это все кнопки
melodramsBtn = telebot.types.KeyboardButton("Мелодрамы?")
actionsBtn = telebot.types.KeyboardButton("Экшн?")
thrillerseBtn = telebot.types.KeyboardButton("Триллеры?")
scaryBtn = telebot.types.KeyboardButton("Ужасы?")
comediesBtn = telebot.types.KeyboardButton("Комедии?")
cartoonsBtn = telebot.types.KeyboardButton("Мультфильмы?")
backBtn = telebot.types.KeyboardButton('? Назад')

rkm.add(detectiveBtn, melodramsBtn, actionsBtn, thrillerseBtn, scaryBtn, comediesBtn, cartoonsBtn, backBtn) # добавление кнопок к клавиатуре

if message.text == "Детективы?":
    @bot.message_handler(commands="add") # команда /add
    def addFilm(message): 
        @bot.message_handler(content_types="photo") # если после комманды отправиди фотку
        def film(message):
            filmType = "детективы" # тип фильма (нужен для бд)
            adding(message, filmType) # ну это само добавление в базу данных

elif message.text == "Мелодрамы?":
    @bot.message_handler(commands="add") 
    def addFilm(message): 
        @bot.message_handler(content_types="photo") 
        def film(message):
            filmType = "мелодрамы" 
            adding(message, filmType)

elif message.text == "Экшн?":
    @bot.message_handler(commands="add") 
    def addFilm(message): 
        @bot.message_handler(content_types="photo") 
        def film(message):
            filmType = "экшн" 
            adding(message, filmType)
            
elif message.text == "Триллеры?":
    @bot.message_handler(commands="add") 
    def addFilm(message): 
        @bot.message_handler(content_types="photo") 
        def film(message):
            filmType = "триллеры" 
            adding(message, filmType)

elif message.text == "Ужасы?":
    @bot.message_handler(commands="add") 
    def addFilm(message): 
        @bot.message_handler(content_types="photo") 
        def film(message):
            filmType = "ужасы" 
            adding(message, filmType)

elif message.text == "Комедии?":
    @bot.message_handler(commands="add") 
    def addFilm(message): 
        @bot.message_handler(content_types="photo") 
        def film(message):
            filmType = "коммедии" 
            adding(message, filmType)

elif message.text == "Мультфильмы?":
    @bot.message_handler(commands="add") 
    def addFilm(message): 
        @bot.message_handler(content_types="photo")
        def film(message):
            filmType = "мультфильмы" 
            adding(message, filmType)

elif message.text == '? Назад':
    mainMenu(message) # главное меню (ну это не нужно для решения данной задачи)
elif message.text != "Детективы?" and message.text != "Мелодрамы?" and message.text != "Экшн?" and message.text != "Триллеры?" and message.text != "Ужасы?" and message.text != "Комедии?" and message.text != "Мультфильмы?" and message.text != "Приключения?" and message.text != "Документальные?" and message.text != '? Назад': # здесь у нас все исключения
    rkm = telebot.types.ReplyKeyboardMarkup(resize_keyboard=True)
    detectiveBtn = telebot.types.KeyboardButton("Детективы?")
    melodramsBtn = telebot.types.KeyboardButton("Мелодрамы?")
    actionsBtn = telebot.types.KeyboardButton("Экшн?")
    thrillerseBtn = telebot.types.KeyboardButton("Триллеры?")
    scaryBtn = telebot.types.KeyboardButton("Ужасы?")
    comediesBtn = telebot.types.KeyboardButton("Комедии?")
    cartoonsBtn = telebot.types.KeyboardButton("Мультфильмы?")
    backBtn = telebot.types.KeyboardButton('? Назад')
    rkm.add(detectiveBtn, melodramsBtn, actionsBtn, thrillerseBtn, scaryBtn, comediesBtn, cartoonsBtn, backBtn)
    msg = bot.send_message(message.chat.id, "Я не понимаю, что вы от меня хотите... Пожалуйста, нажмите на одну из кнопок моего меню, чтобы взаимодействовать со мной", reply_markup=rkm)
    bot.register_next_step_handler(msg, whatToWatch)




def adding(message, typee):

    connect = sqlite3.connect('feedback.db')
    cursor = connect.cursor()

    cursor.execute("""CREATE TABLE IF NOT EXISTS pictures(
        typee STRING NOT NULL,
        pic BLOB NOT NULL
    )""")
    connect.commit()

###############################################
#Я НЕ ЗНАЮ ЧТО ДАЛЬШЕ ДЕЛАТЬ

Ответы (1 шт):

Автор решения: Violet

Пример реализации.

from pathlib import Path


# Сохраним изображение, которое отправил пользователь в папку `/files/%ID пользователя/photos`
@bot.message_handler(content_types=['photo'])
def save_photo(message):
    # создадим папку если её нет
    Path(f'files/{message.chat.id}/photos').mkdir(parents=True, exist_ok=True)

    # сохраним изображение
    file_info = bot.get_file(message.photo[len(message.photo) - 1].file_id)
    downloaded_file = bot.download_file(file_info.file_path)
    src = f'files/{message.chat.id}/' + file_info.file_path
    with open(src, 'wb') as new_file:
        new_file.write(downloaded_file)
    
    # явно указано имя файла!
    # откроем файл на чтение  преобразуем в base64
    with open(f'files/{message.chat.id}/photos/file_0.jpg', "rb") as image_file:
        encoded_string = base64.b64encode(image_file.read())

    # откроем БД и запишем информацию (ID пользователя, base64, подпись к фото)
    conn = sqlite3.connect("test.db")
    cursor = conn.cursor()
    cursor.execute('INSERT INTO users VALUES (?, ?, ?)', (message.chat.id, encoded_string, str(message.caption)))
    conn.commit()


# при получении команды /img от пользователя
@bot.message_handler(commands=['img'])
def ext_photo(message):
    # откроем БД и по ID пользователя извлечём данные base64
    conn = sqlite3.connect("test.db")
    img = conn.execute('SELECT img FROM users WHERE tlgrm_id = ?', (message.chat.id, )).fetchone()
    if img is None:
        conn.close()
        return None
    else:
        conn.close()
        
        # сохраним base64 в картинку и отправим пользователю
        with open("files/imageToSave.jpg", "wb") as fh:
            fh.write(base64.decodebytes(img[0]))
            bot.send_photo(message.chat.id, open("files/imageToSave.jpg", "rb"))
→ Ссылка