Example of implementing asynchronous non-blocking access to the database using Python Tornado framework, pythontornado

Source: Internet
Author: User
Tags install mongodb

Example of implementing asynchronous non-blocking access to the database using Python Tornado framework, pythontornado

Tornado is an http non-blocking server. We will use the tornado framework, mongodb database, and motor (asynchronous driver of mongodb) to implement tornado's non-blocking function.

Download and installation supported by other environments

1. Install mongodb

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

2. Install 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("")db = client.meet

First, connect to the database in the configuration file. In client. db_name, db_name is the database name.

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

Add db () and use the property decoration to access the database like the 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. the coroutine decoration makes the function non-blocking and returns a generator instead of using the callback function. motor also implements Asynchronization through yield (otherwise, a callback function will be returned ). in fact, this example does not reflect the blocking problem. The key is that the time is too short.
Let's modify the code.

# Yield self. db. user. insert (data) # After yield tornado. gen. task (tornado. ioloop. IOLoop. instance (). add_timeout, time. time () + 10)

Tornado is used here. ioloop. IOLoop. instance (). add_timeout blocks the application. This is time. non-blocking implementation of sleep, if time is used here. sleep because it is tornado and a single thread will block the entire application, other handler cannot access it.
You can see that after I register on the registration page, click/auth/login during blocking to directly access the login page to complete non-blocking.

Redirect in asynchronous mode
When using tornado, I often encounter some problems. I would like to write out the problems and solutions (here I would like to thank pythonista for helping me solve these problems)

1. Problem

I want to implement a user registration function. The web framework uses the tornado database to use mongodb, but the Exception redirect error occurs during registration. The following code is posted:

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'user name already exists ', 'error') self. redirect ('/auth/register') _ verify_email = yield self. db. user. find_one ({'email ': email}) if _ verify_email: self. flash (u'email registered ', 'error') self. redirect ('/auth/register') if captcha and captcha = self. get_secure_cookie ('captcha '). replace ('',''): self. flash (u'verification code entered correctly ', 'info') else: self. flash (u'verification code input error', 'error') self. redirect ('/auth/register') password = haslib. md5 (password + self. settings ['SITE']). hexdigest () profile = {'uploadmg ': '', '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 ('/')

If the user verification code is entered incorrectly, the registration page will be displayed. However, if the verification code is incorrect, the system will continue to execute the code. although in self. add self. finish will terminate the code, but because of self. the redirect function already contains self. therefore, the code for abnormal termination is reported twice.
The code will not be terminated because of the above reasons, and the user will still register if the verification code is incorrect.

2. Solution

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



(1) answer provided by rsj217, an enthusiastic user in segmentdefault
Self. finish closes the request because @ tornado. web. aynchronous tells tornado to wait for the request (long link). self. redirect equals to setting the location attribute of headers of response.

(2) answers provided by Yiyun, enthusiastic users in segmentdefault
Self. finish certainly does not jump out of the function. Otherwise, what else do I want to do after the request ends.

3. Summary

The above problem occurs because self. finish is taken out of the function by mistake.

  • Self. redirect will set location in request. headers for redirect
  • Self. finish will close the request, but will not jump out of the Function

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.