Предисловие


Прошу извинения за то, что в первой статье не написал про работу с базой данных, но именно эта часть направлена на работу с MySQL.

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

Подготовка


После прошлой статьи на руках мы должны иметь такой код:

import vk_api
from vk_api.utils import get_random_id
from vk_api.bot_longpoll import VkBotLongPoll, VkBotEventType
import pymysql.cursors
import requests

def getConnection():
    connection = pymysql.connect(host='you_host',
                                 user='you_user',
                                 password='you_password',
                                 db='you_db'
                                 charset='utf8mb4',
                                 cursorclass=pymysql.cursors.DictCursor)
    return connection

<anchor>habracut</anchor>
vk_session = vk_api.VkApi(token="a6f87v8c9a9sa87a7af9a0f9f9v8a6s6c5b5m6n8bds09asc8d7b87d87bd87n")
vk = vk_session.get_api()
longpoll = VkBotLongPoll(vk_session, "637182735")
#Проверка действий 
for event in longpoll.listen():
    if event.type == VkBotEventType.MESSAGE_NEW:
        #Проверяем не пустое ли сообщение нам пришло
        if event.obj.text != '': 
            #Проверяем пришло сообщение от пользователя или нет
            if event.from_user:
                #Отправляем сообщение
                vk.messages.send(
                        user_id=event.obj.from_id,
                        random_id=get_random_id(),
                        message=event.obj.text)

Создадим бота, который будет возвращать нам результат положительный или отрицательный. Например «Life» и «Dead». Потом заносить его в базу данных и в будущем отправлять этот результат нам.

Для начала мы должны иметь свою базу данных с уже готовой таблицей.

Если кто то не умеет создавать таблицы, то вот код, который необходимо вставить будучи в mysql консоли:

CREATE DATABASE `firstbot`;
CREATE TABLE `mode`(Id_User INT(11), Mode VARCHAR(6) DEFAULT("NOT"), PRIMARY KEY(Id_User));

На этом каркас нашей таблицы будет готов. Подробнее о создании и изменении таблиц можно найти на офф. сайте(ссылка будет ниже).

Создадим функцию, которая будет рандомно возвращать Dead или Live:

#Подключим новый модуль random
import random
def randomMode():
    #Получаем рандомное число в районе от 1 до 200
    number = random.randint(1, 200)
    if number % 2 == 0:
        return 'Live'
    else:
        return 'Dead'

Теперь мы должны сделать функцию, которая отправит в базу данных наши значения.

def addToDatabase(functionMode, x):
    #Создаем новую сессию
    connection = getConnection()
    try:
        #Будем получать информацию от сюда
        cursor = connection.cursor()
        #Наш запрос
        sql = "INSERT INTO mode (Id_User, Mode) VALUES (%s, %s)"
        #Выполняем наш запрос и вставляем свои значения
        cursor.execute(sql, (x, functionMode))
        connection.commit()
    #Если пользователь уже есть в бд, то мы обновляем информацию
    except:
        sql = "UPDATE mode SET Mode WHERE Id_User = %s"
        cursor.execute(sql, (functionMode, x))
        connection.commit()
    finally:
        connection.close()
        return functionMode


Мы создали функцию, которая будет добавлять человека в базу данных или заканчивать свою работу, если он уже там есть.

Но помимо того, что мы заносим значения в базу данных, нам надо их получать. Для этого создадим такую функцию.

def selectFromDatabase(idUser):
    connection = getConnection()
    try:
        cursor = connection.cursor()
        sql = "SELECT Mode FROM mode WHERE Id_User = %s"
        cursor.execute(sql, (idUser))
        #Получаем запрашиваемые данных и заносим их в переменные
        for i in cursor:
            modeSend = i['Mode']
            connection.commit()
    except:
        print("Ошибка") 
    finally:
        connection.close()
        return modeSend

Все что нам осталось это собрать код полностью и добавить пару строк, что бы все работало так как мы хотим.

if event.obj.text == 'Попытка':
    if event.from_user:
        idUser  = event.obj.from_id
        vk.messages.send(
                            user_id=event.obj.from_id,
                            random_id=get_random_id(),
                            message="Ваш результат: " + addToDatabase(randomMode(), idUser))
if event.obj.text == 'Прошлый результат':
    if event.from_user:
        idUser = event.obj.from_id
        vk.messages.send(
                            user_id=event.obj.from_id,
                            random_id=get_random_id(),
                            message="Ваш последний: " + selectFromDatabase(idUser))
                            

И таким образом мы получим ответ от нашего бота



Итог


С помощью проделанной работы мы создали бота умеющего работать с MySQL. На этом его функционал не заканчивается. Он намного шире и больше, а ограничен только вашей фантазией.
Код не идеале и писал я его только, что бы показать как работает MySQL. Если вы знаете способы лучше, смело применяйте их. Так же приму любую помощь по усовершенствованию текущего кода.

Полезные ссылки


Официальная страница PyMySQL
Официальная страница MySQL
Документация PyMySQL на русском
Документация vk_api
Документая API Вконтакте

Комментарии (6)


  1. vehubix
    19.05.2019 11:16

    Мама, я уже почти программист! Автору спасибо.


  1. PavelBelyaev
    20.05.2019 09:05
    +1

    Если с ботом будут общаться, например, раз в 3 месяца, не будет ли у него отваливаться соединение с базой? А то у меня на php такое возникало, когда с базой общение происходило редко, модифицировал немного скрипт, чтобы проверяло соединение и переподключалось, может быть в python это уже сразу предусмотрено.
    Я недавно на PHP бота писал для своих задачек, но сделал его на нескольких независимых демонах, один слушает longpool и все приходящие сообщения закидывает в цепочку RabbitMQ, второй подписан на цепочку исходящих (кому и что отправить), ну естественно оттуда разгребает отправку так, что исходящие уходят с соблюдением лимита vkapi…
    Ну и третий демон подписан на цепочку входящих и раскладывает ответы на исходящие.
    Думаю в будущем еще пересмотрю архитектуру, ну пока мне всё нравится, когда php-скрипт подписан на цепочку, то callback функция выполняется молниеносно и есть некая параллельность процессов.


    1. abbaturSF Автор
      20.05.2019 09:09

      Отваливаться не должен. Точно не скажу. На своём опыте бот работал все время, что был включён. Отсоединялся по логике, только когда пк переводился в режим сна. Если на каком то хосте, то не должен вообще никак. Единственное что pythonanywhere, если программа не работает больше ~3 часов, только он ее отключает


  1. bosha
    21.05.2019 08:46

    Статья уровня "я прочитал документацию и смотрите что у меня получилось".


    Код плохой, никакие нормальные современные библиотеки не используются. Нет миграций, никакой нормальной обертки над базой. Хороший пример как писать на python не надо.


    1. abbaturSF Автор
      21.05.2019 08:47

      Какие современные библиотеки посоветуешь?


      1. bosha
        21.05.2019 12:59

        Минимум: alembic для миграций, для работы с БД — sqlalchemy.
        Чаще всего сейчас такие приложения пишут используя asyncio и aiopg.