前言:
  • 需要异步操作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对象

    • 单连接

      1. import peewee_async
      2. # db = peewee_async.MySQLDatabase(database_name, host, port, user, password)
      3. # 或者,将自己的数据库信息封装到字典中
      4. db_setting = {
      5. "user": "root",
      6. "password": "xxxxxx",
      7. "host": "127.0.0.1",
      8. "port": 3306,
      9. "database": "test"
      10. }
      11. db = peewee_async.MySQLDatabase(**db_setting)
    • 连接池

      1. from playhouse.shortcuts import RetryOperationalError
      2. from peewee_async import PooledMySQLDatabase
      3. # 可以自动重新连接的连接池
      4. class RetryMySQLDatabase(RetryOperationalError, PooledMySQLDatabase):
      5. _instance = None
      6. @staticmethod
      7. def get_db_instance():
      8. if not RetryMySQLDatabase._instance:
      9. RetryMySQLDatabase._instance = RetryMySQLDatabase(database_name,
      10. host, port, user, password,
      11. max_connections=10)
      12. return RetryMySQLDatabase._instance
      13. db = RetryMySQLDatabase.get_db_instance()
  • 返回的database对象的一些常用方法

    • get_tables() 返回列表,当前数据库的所有表名

    • get_columns(table_name) 传参表名,返回列表,包含ColumnMetadata对象,字段信息

    • create_tables()

      第一个参数为列表,包含要创建的表model

      第二个参数safe, 不传默认为False,建表的时候如果表已经存在会报错,可以加safe=True

    • is_closed() 判断当前连接是否关闭

    • close() 关闭连接

  • peewee

    • peewee 模块可以参照官方文档用法,和sqlalchemy差别不大,为了下面的操作,暂时建一个model

    book.py

    1. # 集中写一个basemodel,将数据库对象绑定在model上,类才能映射到数据库中的表
    2. class BaseModel(Model):
    3. class Meta:
    4. database = db
    5. class Book(BaseModel):
    6. book_id = PrimaryKeyField() # int 主键自增,在peewee3.10 版本中新增了字段AutoField,表示主键自增
    7. book_name = CharField(max_length=100, verbose_name="书名")
    8. # 鉴于篇幅, 作者表不写,外键第一个参数为model类名,to_field表示关联的字段
    9. 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上
    1. from tornado.web import RequestHandler
    2. from tornado import gen
    3. import tornado.ioloop
    4. from book import Book
    5. class RegHandler(RequestHandler):
    6. async def get(self):
    7. # 在handler类中可以使用绑定到app上的manager对象执行操作,因为是异步操作需要使用await关键字
    8. # 以下两种查询方式返回结果对象格式不同
    9. book_res = await self.application.objects.get(Book, book_name="简爱")
    10. id = book_res.book_id
    11. # 只有调用了execute方法才是执行,query打印可以看到只是生成了sql语句
    12. # 为保证异步调用必须使用peewee-async manager生成的对象执行操作函数,不能使用model的execute执行,会同步阻塞
    13. query = Book.select().where(Book.username=="简爱")
    14. # execute执行返回AsyncQueryWrapper对象,如果有值可以通过下标取出每个book对象
    15. # query 对象执行前可以调用dicts()方法,返回对象内容为字典格式
    16. # query.tuples() 返回对象内容为元组格式,相当于sqlalchemy,fetchall()
    17. # 其他方法或者属性有需要的可以使用dir()方法和getattr()方法查看属性,以及属性调用后返回值
    18. book_res = await self.application.objects.execute(query.dicts())
    19. pass
    20. async def post(self):
    21. from tornado.escape import json_decode
    22. body = json_decode(self.request.body)
    23. # 增
    24. # 如果参数是字典格式,且key值对应字段名称,可以使用peewee model里面的insert方法
    25. await self.application.objects.execute(Book.insert(body))
    26. # 或者使用封装的create方法,create方法源码还是调用了model类的insert方法
    27. await self.application.objects.create(Book, boo_name=body.get("book"), book_auth=2)
    28. pass
    29. app = tornado.web.Application([
    30. (r"/book", BookHandler)
    31. ])
    32. if __name__ == '__main__':
    33. app = tornado.web.Application(urlpaten)
    34. import peewee_async
    35. # 将manager对象绑定到app上
    36. app.objects = peewee_async.Manager(database)
    37. server = httpserver.HTTPServer(app, xheaders=True)
    38. server.listen(80)
    39. tornado.ioloop.IOLoop.current().start()

  • 初步介绍先先写到这里,通过上述介绍使用peewee和peewee-async没有大问题,后面会通过详细功能具体详细介绍使用,细小的api建议看官方文档

  • 有问题欢迎指出,随时修正

tornado+peewee-async+peewee+mysql(一)的更多相关文章

  1. async 配合mysql

    async-db.js const mysql = require('mysql') const pool = mysql.createPool({ host : '127.0.0.1', user ...

  2. 在tornado中使用异步mysql操作

    在使用tornado框架进行开发的过程中,发现tornado的mysql数据库操作并不是一步的,造成了所有用户行为的堵塞.tornado本身是一个异步的框架,要求所有的操作都应该是异步的,但是数据库这 ...

  3. flask+mako+peewee(下)(解决了Error 2006: MySQL server has gone away)

    这篇主要介绍在这次项目中使用的peewee 文档地址:http://peewee.readthedocs.org/en/latest/index.html 首先我们要初始化一个数据库连接对象.这里我使 ...

  4. peewee在flask中的配置

    # 原文:https://blog.csdn.net/mouday/article/details/85332510 Flask的钩子函数与peewee.InterfaceError: (0, '') ...

  5. python轻量级orm框架 peewee常用功能速查

    peewee常用功能速查 peewee 简介 Peewee是一种简单而小的ORM.它有很少的(但富有表现力的)概念,使它易于学习和直观的使用. 常见orm数据库框架 Django ORM peewee ...

  6. Python 操作 MySQL 的5种方式(转)

    Python 操作 MySQL 的5种方式 不管你是做数据分析,还是网络爬虫,Web 开发.亦或是机器学习,你都离不开要和数据库打交道,而 MySQL 又是最流行的一种数据库,这篇文章介绍 Pytho ...

  7. 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 ...

  8. Python 操作 MySQL 的5种方式

    不管你是做数据分析,还是网络爬虫,Web 开发.亦或是机器学习,你都离不开要和数据库打交道,而 MySQL 又是最流行的一种数据库,这篇文章介绍 Python 操作 MySQL 的5种方式,你可以在实 ...

  9. Tornado模块分类和各模块之间的关系

    1. Core web framework tornado.web — 包含web框架的大部分主要功能,包含RequestHandler和Application两个重要的类 tornado.https ...

  10. Tornado模块分类

    Tornado模块分类 1. Core web framework tornado.web — 包含web框架的大部分主要功能,包含RequestHandler和Application两个重要的类 t ...

随机推荐

  1. Python 之并发编程之进程中(守护进程(daemon)、锁(Lock)、Semaphore(信号量))

    五:守护进程 正常情况下,主进程默认等待子进程调用结束之后再结束守护进程在主进程所有代码执行完毕之后,自动终止kill -9 进程号 杀死进程.守护进程的语法:进程对象.daemon = True设置 ...

  2. 使用CSS3动画属性实现各种旋转跳跃

    Transform字面上就是变形,改变的意思.在CSS3中transform主要包括以下几种:旋转rotate.扭曲skew.缩放scale和移动translate以及矩阵变形matrix. tran ...

  3. 「HNOI2003」消防局的设立

    题目 [内存限制:$256 MiB$][时间限制:$1000 ms$] [标准输入输出][题目类型:传统][评测方式:文本比较] 题目描述 2020 年,人类在火星上建立了一个庞大的基地群,总共有 $ ...

  4. ES6之新的数据结构

    Set Set 类似于数组,是一种集合的数据结构,和 Array 之间最大的区别是: Set中所有的成员都是唯一的. 可以把Set想象成是一个: 既没有重复元素,也没有顺序概念的数组. Set 本身是 ...

  5. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 表格:表示成功的操作

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  6. 【剑指Offer面试编程题】题目1516:调整数组顺序使奇数位于偶数前面--九度OJ

    题目描述: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 输入: 每个输 ...

  7. android使用友盟实现第三方登录、分享以及微信回调无反应问题解决办法

    这里介绍微信和新浪登录.微信登录和新浪登录都需要申请第三方账号.可以参考官方文档http://dev.umeng.com/social/android/operation#2还是很清晰的. 新浪微博开 ...

  8. Spring任务调度实战之Quartz Cron Trigger

    在Quartz中除了使用最简单的Simple Trigger以外,也可以使用类似Linux上Cron作业的CronTrigger的方式来运行Job,下面是一个小例子: 1. 首先是一个任务类,这个类没 ...

  9. hdu 1533 Going Home 最小费用最大流 (模板题)

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  10. PHP开发环境(Apache+mysql+PHPstorm+php)的搭建

    一.搭建思路 从浏览器到web服务器(Apache)到PHP环境到mysql数据库 二.环境搭建 1.浏览器(略) 2.Apache的安装与配置 1)官方下载地址:https://httpd.apac ...