Работа с MySQL в Tornado.

Basics of Python and Django. -> Работа с MySQL с использованием фреймворка Tornado. CRUD операции.

Tornado Mysql.

Создать соединение с Mysql сервером с помощью библиотеки pymysql.

connection = pymysql.connect(
    host='localhost',
    user='root',
    password='1q2w3e',
    db='test',
    charset='utf8mb4',
    cursorclass=DictCursor
)

Для того чтобы закрывать соединение при остановке сервера нам нужно добавить пару методов в класс приложения.

class MyApplication(tornado.web.Application):
    is_closing = False

    def signal_handler(self, signum, frame):
        print('exiting...')
        self.is_closing = True

    def try_exit(self):
        if self.is_closing:
            # clean up here
            tornado.ioloop.IOLoop.instance().stop()
            print('closing MySQL connection')
            connection.close()

Метод signal_handler будет задействован при передачи сигнала останова сервера от операционной системы.

В этом методе мы просто сбрасываем флаг is_closing.

Теперь привяжем сигнал к методу и периодично будем проверать флаг is_closing поставив метод try_exit в периодичный колбэк в 0.1 сек.

if __name__ == "__main__":
    app = make_app() 
    ....
    signal.signal(signal.SIGINT, app.signal_handler)
    tornado.ioloop.PeriodicCallback(app.try_exit, 100).start()
    tornado.ioloop.IOLoop.current().start()

Выборка данных.

class ContactHendler(tornado.web.RequestHandler):
    def get(self):
        with connection.cursor() as cursor:
            query = """
            SELECT
                name
            FROM
                users
            """
            cursor.execute(query)
        tpl = loader.load("contact.html").generate(data=cursor) 
        self.write(tpl)

Шаблон.

  {% for d in data %}
    <tr>
      <th scope="row">1</th>
      <td>{{ d['name'] }}</td>
      <td></td>
      <td></td>
    </tr>
  {% end  %}

Вставка данных.

def post(self):
    email = self.get_argument("email")
    name = self.get_argument("name")
    phone = self.get_argument("phone")
    with connection.cursor() as cursor:
        sql = "INSERT INTO users (email, name, phone) VALUES ('%s', '%s', '%s')" % \
            (email, name, phone)
        cursor.execute(sql)
        connection.commit()
    self.redirect('/')

Шаблон формы.

<form method="POST" action="/" >
    <div class="form-group">
        <label for="exampleInputPassword1">Name</label>
        <input type="text" class="form-control" name="name">
    </div>

    <div class="form-group">
        <label for="exampleInputPassword1">Phone</label>
        <input type="text" class="form-control" name="phone">
    </div>

    <div class="form-group">
      <label for="exampleInputEmail1">Email</label>
      <input type="text" class="form-control" name="email">
    </div>

    <button type="submit" class="btn btn-primary">Submit</button>
  </form>

Удаление данных.

Класс - обработчик.

class DeleteContactHendler(tornado.web.RequestHandler):
    def get(self,id):
        with connection.cursor() as cursor:
            sql = "delete from users where id=%s" % id
            cursor.execute(sql)
            connection.commit()
        self.redirect('/')

Роутинг.

def make_app():
    return MyApplication([
        ...
        (r"/delete/([^/]*)", DeleteContactHendler),
        ...
    ], autoreload=True)

Шаблон.

  {% for d in data %}
<tr>
  <th scope="row">{{ d['id']  }}</th>
  <td>{{ d['name'] }}</td>
  <td>{{ d['email'] }}</td>
  <td>{{ d['phone'] }}</td>
  <td><a href="/delete/{{ d['id']  }}">Delete</a></td>
</tr>
{% end  %}

Редактирование данных.

Класс-обработчик.

class EditContactHendler(tornado.web.RequestHandler):
    def get(self,id):
        with connection.cursor() as cursor:
            sql = "select * from users where id=%s" % id
            cursor.execute(sql)
            tpl = loader.load("edit.html").generate(contact=cursor.fetchone()) 
            self.write(tpl) 
    def post(self,id):
        email = self.get_argument("email")
        name = self.get_argument("name")
        phone = self.get_argument("phone")
        with connection.cursor() as cursor:
            sql = "update users set email='%s', name='%s', phone='%s' where id=%s" % \
                (email, name, phone, id)
            cursor.execute(sql)
            self.redirect('/')

Роутинг.

def make_app():
    return MyApplication([
        ...
        (r"/edit/([^/]*)", EditContactHendler),
       ...
    ], autoreload=True)

Шаблон edit.html

{% extends "layout.html" %}

{% block content %}
<h1>Edit {{ contact['name']  }}</h1>



<form method="POST" action="/edit/{{contact['id']}}" >
    <div class="form-group">
        <label for="exampleInputPassword1">Name</label>
        <input type="text" class="form-control" name="name" value="{{ contact['name'] }}">
    </div>

    <div class="form-group">
        <label for="exampleInputPassword1">Phone</label>
        <input type="text" class="form-control" name="phone" value="{{ contact['phone'] }}">
    </div>

    <div class="form-group">
      <label for="exampleInputEmail1">Email</label>
      <input type="text" class="form-control" name="email" value="{{ contact['email'] }}">
    </div>

    <button type="submit" class="btn btn-primary">Submit</button>
  </form>

{% end %}