Работа с 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 %}