侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Python的Tornado框架实现异步非阻塞访问数据库的示例

Python  /  管理员 发布于 7年前   195

tornado即是一个http非阻塞服务器, 就要用起来, 我们将用到tornado框架 ,mongodb数据库 以及motor(mongodb的异步驱动).来简单实现tornado的非阻塞功能.

其他环境支持的下载与安装

1.安装mongodb

$ sudo apt-get install update$ sudo apt-get install mongodb

2.安装motor

$ pip install motor

非阻塞

# conf.pyimport osimport motorfrom handlers import index, authBASE_DIR = os.path.join(__file__)handlers = [  (r'^/$', index.IndexHandler),  (r'^/auth/register$', auth.RegisterHandler),  (r'^/auth/login$', auth.LoginHandler),]settings = dict(  debug = True,  template_path = os.path.join(BASE_DIR, 'templates'),  static_path = os.path.join(BASE_DIR, 'static'),)client = motor.MotorClient("127.0.0.1")db = client.meet

首先在配置文件中连接数据库, client.db_name中 db_name就是数据库的名称

 # handlers/__init__.pyclass BaseHandler(tornado.web.RequestHandler, TemplateRendering):  def initialite(self):    ...  @property  def db(self):    return self.application.db

添加db()并使用property装饰,像属性一样访问数据库.

# auth.pyimport os import time import tornado.webfrom tornado import genfrom . import BaseHandlerclass RegisterHandler(BaseHandler):  def get(self):    self.render_html('register.html')  @tornado.web.asynchronous  @gen.coroutine  def post(self):    username = self.get_argument('username', None)    email = self.get_argument('email', None)    password = self.get_argument('password', None)    data = {      'username': username,      'email': email,      'password': password,      'timestamp': time.time() * 1000,    }    if username and email:      yield self.db.user.insert(data)    self.redirect('/')class LoginHandler(BaseHandler):    @tornado.web.asynchronous  @gen.coroutine  def get(self):    username = self.get_argument('useranme')    user = yield self.db.user.find_one({'username': username})    self.render_html('login.html', user=user)

@gen.coroutine装饰使函数非阻塞, 返回一个生成器, 而不用在使用回调函数. motor也通过yield 实现异步(不然还得返回一个回调函数). 其实这个例子反映不了阻塞问题关键是时间太短.
我们修改一下代码

# 之前yield self.db.user.insert(data)# 之后yield tornado.gen.Task(tornado.ioloop.IOLoop.instance().add_timeout, time.time() + 10)

这里通过tornado.ioloop.IOLoop.instance().add_timeout阻塞应用, 这是time.sleep的非阻塞实现, 如果这里使用time.sleep因为是tornado是单线程会阻塞整个应用所以别的handler也无法访问.
可以看到我在注册页面注册后,在阻塞期间点击/auth/login直接就访问了login页完成非阻塞.

异步下的redirect问题
在使用tornado的时候常常遇到一些问题, 特将遇到的问题和解决的方法写出来(这里的感谢一下帮我解答疑惑的pythonista们)

1.问题

我想要实现一个注册用户功能, web框架使用tornado数据库使用mongodb但在注册时出现Exception redirect的错误. 现贴下代码:

class Register(BaseHandler):  def get(self):    self.render_html('register.html')  @tornado.web.aynchronous  @gen.coroutine  def post(self):    username = self.get_argument('username')    email = self.get_argument('email')    password = self.get_argument('password')    captcha = self.get_argument('captcha')    _verify_username = yield self.db.user.find_one({'username': username})    if _verify_username:      self.flash(u'用户名已存在', 'error')      self.redirect('/auth/register')    _verify_email = yield self.db.user.find_one({'email': email})    if _verify_email:      self.flash(u'邮箱已注册', 'error')      self.redirect('/auth/register')    if captcha and captcha == self.get_secure_cookie('captcha').replace(' ',''):      self.flash(u'验证码输入正确', 'info')    else:      self.flash(u'验证码输入错误', 'error')      self.redirect('/auth/register')    password = haslib.md5(password + self.settings['site']).hexdigest()    profile = {'headimg': '', 'site': '', 'job': '', 'signature':'',          'github': '', 'description': ''}    user_profile = yield self.db.profile.insert(profile)    user = {'username': username, 'email': email, 'password': password,        'timestamp': time.time(), 'profile_id': str(user_profile)}    yield self.db.user.insert(user)    self.set_secure_cookie('user', username)    self.redirect('/')

本想如果用户验证码输入出错就跳转到注册页面, 但问题是验证码出错也会继续执行一下代码. 虽然在self.redirect后加上self.finish会终止代码,但是因为self.redirect 函数内已有self.finish所以出现了两次报出异常终止的代码.
因为以上原因代码不会被终结, 验证码出错用户还是会注册.

2.解决方案

return self.redirect('/auth/register')

或

self.redirect('/auth/register')return

(1)segmentdefault中热心用户rsj217给出的答案
self.finish 会关掉请求, 因为@tornado.web.aynchronous告诉tornado会一直等待请求(长链接). self.redirect等于设置了response的headers的location属性.

(2)segmentdefault中热心用户依云给出的答案
self.finish当然不会跳出函数, 不然请求结束之后还想做些事情怎么办呢.

3.总结

因为错把self.finish当做跳出函数出现了以上的问题

  • self.redirect会在request.headers 里设置location用于跳转
  • self.finish会关掉请求, 但不会跳出函数

您可能感兴趣的文章:

  • python利用JMeter测试Tornado的多线程
  • python tornado修改log输出方式
  • python tornado使用流生成图片的例子
  • python-tornado的接口用swagger进行包装的实例
  • 关于Python核心框架tornado的异步协程的2种方法详解
  • python tornado微信开发入门代码
  • Tornado Web Server框架编写简易Python服务器
  • python使用tornado实现登录和登出
  • python使用tornado实现简单爬虫
  • Python tornado队列示例-一个并发web爬虫代码分享
  • Tornado协程在python2.7如何返回值(实现方法)
  • python用装饰器自动注册Tornado路由详解
  • 深入解析Python的Tornado框架中内置的模板引擎
  • 使用Python的Tornado框架实现一个Web端图书展示页面
  • 为Python的Tornado框架配置使用Jinja2模板引擎的方法
  • Python的Tornado框架实现图片上传及图片大小修改功能
  • Python的Tornado框架的异步任务与AsyncHTTPClient
  • Python对Tornado请求与响应的数据处理


  • 上一条:
    Python的Flask框架中的Jinja2模板引擎学习教程
    下一条:
    Python的Tornado框架实现图片上传及图片大小修改功能
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客