Сохранить отправленное пользователем изображение в БД 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"))