tornado+peewee-async+peewee+mysql(一)
前言:
- 需要异步操作MySQL,又要用orm,使用sqlalchemy需要加celery,觉得比较麻烦,选择了peewee-async
开发环境 python3.6.8+peewee-async0.5.12+peewee2.10.2
数据库:MySQL,使用peewee-async需要依赖库 pip install aiomysql
peewee-async,对peewee版本只支持peewee<=2.10.2,>=2.8.0
python3.5以后使用async和await关键字实现原生协程,也可以使用tornado的gen模块下coroutine实现协程,或者asyncio模块实现协程,下文统一使用async和await
tornado 异步调用MySQL
爬坑
最初遇到的坑,使用了最新版的peewee,连接池连接,也使用了async和await协程,但是怎么调用都会阻塞,后来发现不是阻塞单个协程,是阻塞了整个进程,因为tornado是单进程,必须数据库也使用异步操作,才能不阻塞整个进程
pip install peewee-async 的时候默认会安装符合版本要求的peewee,想用最新的peewee模块可以使用--pre
查看peewee-async 模块的MySQLDatabase,继承了AsyncDatabase和peewee.MySQLDatabase,AsyncDatabase方法全部使用协程实现异步
peewee-async 连接MySQL,返回database对象
单连接
import peewee_async
# db = peewee_async.MySQLDatabase(database_name, host, port, user, password)
# 或者,将自己的数据库信息封装到字典中
db_setting = {
"user": "root",
"password": "xxxxxx",
"host": "127.0.0.1",
"port": 3306,
"database": "test"
}
db = peewee_async.MySQLDatabase(**db_setting)
连接池
from playhouse.shortcuts import RetryOperationalError
from peewee_async import PooledMySQLDatabase
# 可以自动重新连接的连接池
class RetryMySQLDatabase(RetryOperationalError, PooledMySQLDatabase):
_instance = None @staticmethod
def get_db_instance():
if not RetryMySQLDatabase._instance:
RetryMySQLDatabase._instance = RetryMySQLDatabase(database_name,
host, port, user, password,
max_connections=10)
return RetryMySQLDatabase._instance db = RetryMySQLDatabase.get_db_instance()
返回的database对象的一些常用方法
get_tables() 返回列表,当前数据库的所有表名
get_columns(table_name) 传参表名,返回列表,包含ColumnMetadata对象,字段信息
create_tables()
第一个参数为列表,包含要创建的表model
第二个参数safe, 不传默认为False,建表的时候如果表已经存在会报错,可以加safe=Trueis_closed() 判断当前连接是否关闭
close() 关闭连接
peewee
- peewee 模块可以参照官方文档用法,和sqlalchemy差别不大,为了下面的操作,暂时建一个model
book.py
# 集中写一个basemodel,将数据库对象绑定在model上,类才能映射到数据库中的表
class BaseModel(Model):
class Meta:
database = db
class Book(BaseModel):
book_id = PrimaryKeyField() # int 主键自增,在peewee3.10 版本中新增了字段AutoField,表示主键自增
book_name = CharField(max_length=100, verbose_name="书名")
# 鉴于篇幅, 作者表不写,外键第一个参数为model类名,to_field表示关联的字段
book_auth = ForeignKeyField(User, to_field="user_id", verbose_name="作者id")
peewee-async Manager
- 管理数据库操作,实现异步操作数据库必须使用Manager,查看源码可以看到,类中的get, create, execute等方法都是使用装饰器@asyncio.coroutine加yield from,在原有的数据库操作基础上做了封装
- 初始化传入数据库连接对象,生成manager对象,使用该对象完成数据库操作,在tornado中一般选择绑定到app上
from tornado.web import RequestHandler
from tornado import gen
import tornado.ioloop
from book import Book class RegHandler(RequestHandler):
async def get(self):
# 在handler类中可以使用绑定到app上的manager对象执行操作,因为是异步操作需要使用await关键字
# 以下两种查询方式返回结果对象格式不同
book_res = await self.application.objects.get(Book, book_name="简爱")
id = book_res.book_id
# 只有调用了execute方法才是执行,query打印可以看到只是生成了sql语句
# 为保证异步调用必须使用peewee-async manager生成的对象执行操作函数,不能使用model的execute执行,会同步阻塞
query = Book.select().where(Book.username=="简爱")
# execute执行返回AsyncQueryWrapper对象,如果有值可以通过下标取出每个book对象
# query 对象执行前可以调用dicts()方法,返回对象内容为字典格式
# query.tuples() 返回对象内容为元组格式,相当于sqlalchemy,fetchall()
# 其他方法或者属性有需要的可以使用dir()方法和getattr()方法查看属性,以及属性调用后返回值
book_res = await self.application.objects.execute(query.dicts())
pass
async def post(self):
from tornado.escape import json_decode
body = json_decode(self.request.body)
# 增
# 如果参数是字典格式,且key值对应字段名称,可以使用peewee model里面的insert方法
await self.application.objects.execute(Book.insert(body))
# 或者使用封装的create方法,create方法源码还是调用了model类的insert方法
await self.application.objects.create(Book, boo_name=body.get("book"), book_auth=2)
pass app = tornado.web.Application([
(r"/book", BookHandler)
]) if __name__ == '__main__':
app = tornado.web.Application(urlpaten)
import peewee_async
# 将manager对象绑定到app上
app.objects = peewee_async.Manager(database)
server = httpserver.HTTPServer(app, xheaders=True)
server.listen(80)
tornado.ioloop.IOLoop.current().start()
初步介绍先先写到这里,通过上述介绍使用peewee和peewee-async没有大问题,后面会通过详细功能具体详细介绍使用,细小的api建议看官方文档
有问题欢迎指出,随时修正
tornado+peewee-async+peewee+mysql(一)的更多相关文章
- async 配合mysql
async-db.js const mysql = require('mysql') const pool = mysql.createPool({ host : '127.0.0.1', user ...
- 在tornado中使用异步mysql操作
在使用tornado框架进行开发的过程中,发现tornado的mysql数据库操作并不是一步的,造成了所有用户行为的堵塞.tornado本身是一个异步的框架,要求所有的操作都应该是异步的,但是数据库这 ...
- flask+mako+peewee(下)(解决了Error 2006: MySQL server has gone away)
这篇主要介绍在这次项目中使用的peewee 文档地址:http://peewee.readthedocs.org/en/latest/index.html 首先我们要初始化一个数据库连接对象.这里我使 ...
- peewee在flask中的配置
# 原文:https://blog.csdn.net/mouday/article/details/85332510 Flask的钩子函数与peewee.InterfaceError: (0, '') ...
- python轻量级orm框架 peewee常用功能速查
peewee常用功能速查 peewee 简介 Peewee是一种简单而小的ORM.它有很少的(但富有表现力的)概念,使它易于学习和直观的使用. 常见orm数据库框架 Django ORM peewee ...
- Python 操作 MySQL 的5种方式(转)
Python 操作 MySQL 的5种方式 不管你是做数据分析,还是网络爬虫,Web 开发.亦或是机器学习,你都离不开要和数据库打交道,而 MySQL 又是最流行的一种数据库,这篇文章介绍 Pytho ...
- MySQL server has gone away && Lost connection to MySQL server during query
问题一.MySQL server has gone away ##### peewee from peewee import * from peewee import __exception_wrap ...
- Python 操作 MySQL 的5种方式
不管你是做数据分析,还是网络爬虫,Web 开发.亦或是机器学习,你都离不开要和数据库打交道,而 MySQL 又是最流行的一种数据库,这篇文章介绍 Python 操作 MySQL 的5种方式,你可以在实 ...
- Tornado模块分类和各模块之间的关系
1. Core web framework tornado.web — 包含web框架的大部分主要功能,包含RequestHandler和Application两个重要的类 tornado.https ...
- Tornado模块分类
Tornado模块分类 1. Core web framework tornado.web — 包含web框架的大部分主要功能,包含RequestHandler和Application两个重要的类 t ...
随机推荐
- Python 爬取 北京市政府首都之窗信件列表-[信息展示]
日期:2020.01.25 博客期:133 星期六 [代码说明,如果要使用此页代码,必须在本博客页面评论区给予说明] //博客总体说明 1.准备工作 2.爬取工作 3.数据处理 4.信息展示(本期博客 ...
- autoit 《FAQ 大全》
常见问题: Q1 如何调试脚本? MsgBox(0,"测试",$var) ConsoleWrite("var=" & $var & @CRLF ...
- 【剑指Offer面试编程题】题目1384:二维数组中的查找--九度OJ
题目描述: 在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 输入: 输入可能包含 ...
- 使用U盘安装Linux最美桌面发行版Elementary OS 及常用开发环境配置(JDK,Redis,MySQL,Docker,IDEA,STS)
前言 假期在家无聊,刚好把六年前的一台笔记本电脑利用起来,原来电脑虽然说配置说不上古董机器,但是运行win系统感觉还是不流畅,所幸给换成Linux桌面版系统,在网上查阅了很多,Linux桌面系统要么推 ...
- Tomcat能启动,无法访问方法,
好像没有扫描到controller 好像配置文件都没有加载成功 项目启动后,目录下多出一个ssmtest.xml文件 D:\Program Files\JDK-tomcat\apache-tomcat ...
- BEC合约整数溢出漏洞还原与分析
一.币圈一秒,人间一年 有道是币圈一日,人间一年.这个说法又得升级了,叫币圈一秒,人间一年. 前不久,币圈又出大事啦.BEC智能合约被爆出整数溢出漏洞,导致黑客能无限印币,在一次交易中,也就那么几秒钟 ...
- 偶然遇见:Cayley定理
看到\(purfer\)序列板子后,想到这个名词在哪见过,于是找到了一个题,还带出一个: \(T1\). 题目链接:P4430 小猴打架 开始极其懵逼,考虑过大力容斥,但还是失败了,原来是: Cayl ...
- Unity初识项目结构与面板
一.Unity的项目结构 Unity中的一个项目是有若干个场景组成的,每一个场景又是由若干个游戏对象组成的,每一个游戏对象身上有若干个组件,每一个组件有若干个属性. 项目——>场景——>游 ...
- 树莓派4b烧录系统
树莓派4b烧录系统 树莓派 型号:树莓派4b 系统:raspbian-buster-full 1.先用SDFormatterv4格式化sd卡 2.用win32diskimager-v0.9-binar ...
- 01.DesignParttern设计模式,简单工厂,工厂方法,抽象工厂三大工厂的区别与联系
工厂用来生产对象,对象具有方法和属性. 简单工厂的缺点(简单工厂并不是23中设计模式): 工厂类的职责相对过重,增加新的产品,需要修改工厂类的判断逻辑,违背开闭原则: JDK源 ...