sanic(4):增加mysql数据库与redis支持 ## 项目结构 依据上文,我们已经可以做出后台,也能使用jinja2来渲染页面。下面简单讲讲如何给sanic项目添加mysql和redis支持。 ``` |-- README.md |-- app.py |-- handlers | |-- __init__.py | |-- __pycache__ | |-- admin_api | |-- index.py |-- run_qb_games.py |-- shutdown.sh |-- sql.txt |-- srvconf.py |-- templates | |-- 404_v3.html | |-- 500_v3.html | `-- web | |-- index.html ``` ## 安装插件 sanic可以开心的使用异步mysql与异步redis,首先需要的是安装插件,当然,mysql和redis的服务是必须有的。本文就不涉及了。 ``` python3.6 -m pip install aioredis python3.6 -m pip install aiomysql ``` ## 初始化 安装完毕后,打开app.py文件。在之前的`setup_db_redis`函数中添加内容: ``` @app.listener('before_server_start') async def setup_db_redis(app, loop): app.db = await aiomysql.create_pool( host=srvconf.mysql_host, port=srvconf.mysql_port, user=srvconf.mysql_user, password=srvconf.mysql_password, db=srvconf.database, loop=loop, charset='utf8', autocommit=True) app.redis_pool = await aioredis.create_pool( (srvconf.redis_host, srvconf.redis_port), minsize=5, maxsize=10, loop=loop ) ... ``` 在项目运行的时候,将db pool和redis pool保存到app对象中。 ## 项目结束关闭资源 创建了pool,在项目关闭的时候就得把资源释放。在app.py中添加代码如下: ``` @app.listener('after_server_stop') async def close_db_redis(app, loop): app.db.close() await app.db.wait_closed() app.redis_pool.close() await app.redis_pool.wait_closed() ``` ## mysql操作 涉及到数据库话题就很大了,在本文中,只讲简单的操作,不涉及高级用法,具体见aiomysql的文档。 ### 查询 使用mysql pool创建一个查询,代码如下: ``` async with app.db.acquire() as conn: async with conn.cursor(aiomysql.DictCursor) as cur: await cur.execute(self.sql, self.values) r = await cur.fetchall() ``` 注意,在self.sql中是需要参数化传值的。用`%s`做占位符。 `r`返回一个数组,每行是一个字典。字典的Key为数据库字段,值为数据值。 ### 删除、修改 ``` async with app.db.acquire() as conn: async with conn.cursor() as cur: await cur.execute(self.sql, self.values) ret = await conn.commit() return ret ``` ### 新增 如果插入一个行新的内容,希望得到自动增长的ID。此时,可以使用`lastrowid`获取: ``` async with app.db.acquire() as conn: async with conn.cursor() as cur: await cur.execute(self.sql, self.values) await conn.commit() ret = cur.lastrowid return ret ``` ## redis使用 安装好了redis和相关的py插件,就能在sanic中轻松使用了。 ### get值 ``` async with app.redis_pool.get() as redis: response = await redis.get(key) ``` ### set值,并设置timeout ``` async with app.redis_pool.get() as redis: await redis.setex(key, timeout, response_cached) ``` 还有一些其它的高级用法,请查看aioredis的文档吧。 来自 大脸猫 写于 2017-07-17 14:17 -- 更新于2020-10-19 13:06 -- 0 条评论