這篇我們使用Torando實現(xiàn)一個留言板的功能,和之前學(xué)習(xí)Django一樣。
新增數(shù)據(jù)庫message數(shù)據(jù)表message。
在tornado中讀取MySQL數(shù)據(jù)需要使用使用支持異步的驅(qū)動,我們使用的是aiomysql。
因為aiomysql的底層是基于asyncio的,所以可以直接在tornado中使用(需要時python3+的環(huán)境)。
aiomysql的github地址
我們看下使用SQL語言的Basic Example.
from aiomysql import create_pool
async def go():
# 創(chuàng)建鏈接是耗時的 IO 操作
async with create_pool(host='127.0.0.1', port=3306,
user='root', password='root',
db='message', charset="utf8") as pool:
# acquire 也是涉及到 socket 的
async with pool.acquire() as conn:
async with conn.cursor() as cur:
# execute 是需要等待的
await cur.execute("SELECT * from message")
value = await cur.fetchone()
print(value)
# 從socket 中取數(shù)據(jù) 網(wǎng)絡(luò)耗時 都是需要 await
if __name__ == "__main__":
from tornado import ioloop
# 這個 ioloop 是單例模式 我們使用 tornado 的 ioloop
io_loop = ioloop.IOLoop.current()
# 上面定義的是協(xié)程因此我們需要協(xié)程的調(diào)用方式
io_loop.run_sync(go)
上面是單獨使用的,我們集成到tornado中使用。
首先是設(shè)置數(shù)據(jù)庫。
settings = {
"static_path": "static",
"static_url_prefix": "/static/",
"template_path": "templates",
"db": {
"host": "127.0.0.1",
"user": "root",
"password": "root",
"name": "message",
"port": 3306
}
}
那怎么將設(shè)置的db配置到鏈接中呢?
if __name__ == "__main__":
app = web.Application([
("/", MainHandler, {"db": settings["db"]}),
("/static/(.*)", StaticFileHandler, {"path": "static"})
], debug=True, **settings)
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
我們使用初始化方法在initialize中設(shè)置,通過傳遞參數(shù)。
class MainHandler(web.RequestHandler):
def initialize(self, db):
self.db = db
async def get(self, *args, **kwargs):
id = ""
name = ""
email = ""
address = ""
message = ""
async with create_pool(host=self.db["host"], port=self.db["port"],
user=self.db["user"], password=self.db["password"],
db=self.db["name"], charset="utf8") as pool:
async with pool.acquire() as conn:
async with conn.cursor() as cur:
await cur.execute("SELECT id, name, email, address, message from message")
try:
id, name, email, address, message = await cur.fetchone()
except Exception as e:
pass
self.render("message.html", id=id, email=email, name=name, address=address, message=message)
這樣子我們就完成個一個頁面獲取值,返回到模板。
現(xiàn)在使用form表單提交修改數(shù)據(jù)。
async def post(self, *args, **kwargs):
id = self.get_body_argument("id", "")
name = self.get_body_argument("name", "")
email = self.get_body_argument("email", "")
address = self.get_body_argument("address", "")
message = self.get_body_argument("message", "")
async with create_pool(host=self.db["host"], port=self.db["port"],
user=self.db["user"], password=self.db["password"],
db=self.db["name"], charset="utf8") as pool:
async with pool.acquire() as conn:
async with conn.cursor() as cur:
if not id:
await cur.execute(
"INSERT INTO message(name, email, address, message) VALUES('{}','{}','{}','{}')".format(name,
email,
address,
message))
else:
await cur.execute("update message set name='{}', email='{}', address='{}', message='{}'".format(name, email, address, message))
await conn.commit()
self.render("message.html", id=id, email=email, name=name, address=address, message=message)
我們使用get_body_argument獲得form參數(shù)的值。