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

import os

import motor

from handlers import index, auth

BASE_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__.py

class BaseHandler(tornado.web.RequestHandler, TemplateRendering):

def initialite(self):

...

@property

def db(self):

return self.application.db

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

# auth.py

import os

import time

import tornado.web

from tornado import gen

from . import BaseHandler

class 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异步查询数据库_Python的Tornado框架实现异步非阻塞访问数据库的示例相关推荐

  1. python自动化测试教程百度云盘_Python接口自动化测试框架实战视频教程百度云下载...

    主流的Fiddler.Requests.Unittest.Mock等接口测试工具/框架应用 进阶自动化框架设计开发 课程目录: 1-1 接口自动化测试从基础到框架-导学 1-2 接口基础知识回顾 1- ...

  2. python网络编程库_python网络编程学习笔记(9):数据库客户端

    一.DB-API概述 python支持很多不同的数据库.由于不同的卖家服务器导致和数据库通信的网络协议各有不同.在python的早期版本中,每一种数据库都带有自己的python模块,所有这些模块以不同 ...

  3. mysql异步查询 java_java 手写并发框架(一)异步查询转同步的 7 种实现方式

    序言 本节将学习一下如何实现异步查询转同步的方式,共计介绍了 7 种常见的实现方式. 思维导图如下: 异步转同步 业务需求 有些接口查询反馈结果是异步返回的,无法立刻获取查询结果. 比如业务开发中我们 ...

  4. python制作查询软件_python 制作本地应用搜索工具

    一.准备工作 请确保已经安装tkinter.pyperclip.threading 二.预览 1.启动 这是程序启动的主界面. 2.运行 搜索之后的界面. 3.结果 选择应用,右击鼠标复制它的下载链接 ...

  5. [转载] python字典查询功能_Python中的字典功能

    参考链接: Python中的字典dictionary方法 (cmp(), len(), items()-) python字典查询功能 Let's check out some important fu ...

  6. Mybatis源码分析之(四)mapper访问数据库的底层原理(代理方法中具体访问数据库的细节)

    从之前的文章,我们知道了其实mapper真正执行的方法就下面的最后两行.(以下所有的分析都基于一次mybatis的一次select查询. MapperProxy类中的invoke函数 public O ...

  7. python监听多个udp端口_尝试实现非阻塞python-udp多端口获取wierd异常

    我试图实现一个非阻塞的pythonudp服务器,它监听多个端口.在 我在这个Stackover posting中找到了一些代码,并将其修改为监听多个套接字,到目前为止,非常好.在 我的代码如下.在#! ...

  8. python接口自动化测试框架链接数据库_python接口自动化测试框架实现之操作mysq数据库...

    python操作mysql数据库需要使用到mysqlclient库. 安装:pip install mysqlclient python连接mysql数据库分以下步骤: 1.与mysql建立连接: 2 ...

  9. python异步处理请求_python:tornado+wsgi异步处理请求

    tornado版本: start_app.py # coding:gbk import tornado.web import tornado.wsgi import wsgiref.simple_se ...

最新文章

  1. 信标节能电路模块第二版本调试-无线充电-2021-3-21
  2. 实至名归!ACM宣布深度学习三巨头共同获得图灵奖
  3. php图书信息浏览器,使PHP即时输出结果到浏览器
  4. php 开启 pathinfo,nginx下PHP开启pathinfo模式
  5. java中ThreadPool的介绍和使用
  6. java char指针数组_简单总结C语言中各种类型的指针的概念
  7. java实现layui分页_layui如何实现数据分页功能
  8. 基于Tensorflow实现DeepFM
  9. 单目3D目标检测方法CaDDN解读
  10. vs2008 在 win7 64位安装问题 office 2003 office 2007兼容问题
  11. Word无法打开该文件,因为文件格式与文件扩展名不匹配。Microsoft Word无法从该位置打开扩展名为.asd的文件。请将此文件移动到原始.asd位置,然后重试。
  12. 2008-09赛季NBA直播表(cctv5 广东体育)
  13. html 字体模糊,详解css3使用transform出现字体模糊的解决办法
  14. 关联关系和依赖关系的思考
  15. Verilog中parameter使用
  16. T语言与快速开发平台之天宇联iOS开发手册
  17. 智能开发血压计模块方案
  18. JavaScript(一)——什么是JavaScript
  19. 潍坊正大光明老年病医院开展防患于未“燃”消防安全演练活动
  20. 2019年参加 PMP 认证考试了,通过的人心得分享

热门文章

  1. vb.net 设置桌面壁纸
  2. 联想ghost重装系统_如何使用ghost手动安装系统_手动ghost安装系统图文步骤
  3. Centos7脚本一键优化
  4. 面向建筑应用的三维点云数据获取和处理的计算方法
  5. AI技术 | PIFuHD-由高清图片生成3D人物模型对BIM的启示
  6. 电脑上总显示宽带连接服务器怎么办啊,电脑显示宽带已连接但网页打不开怎么办...
  7. 小众又冷门的手帐,居然也是一个非常赚钱的项目
  8. 一种基于最大吸收功率的卫星太阳能电池板安装方案
  9. Redis4.0、5.0、6.0、7.0特性整理(持续更新)
  10. 实现点击不同的按钮显示不同的内容【同一页面】web