ホームページ >バックエンド開発 >Python チュートリアル >Python の Tornado フレームワークは、データベースへの非同期ノンブロッキング アクセスを実装します。
tornado は http ノンブロッキング サーバーです。これを使用するには、tornado フレームワーク、mongodb データベース、モーター (mongodb の非同期ドライバー) を使用して、tornado のノンブロッキング機能を簡単に実装します。とインストール
1. mongodbをインストールします
$ sudo apt-get install update
$ sudo apt-get install mongodb
ノンブロッキング
$ pip install motorまずデータベースに接続します構成ファイル、 client.db_name の db_name はデータベースの名前です
# 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.meetdb() を追加し、プロパティ デコレーションを使用してプロパティのようにデータベースにアクセスします。
# handlers/__init__.py class BaseHandler(tornado.web.RequestHandler, TemplateRendering): def initialite(self): ... @property def db(self): return self.application.db@gen.coroutine 装飾関数を非ブロッキングにし、コールバック関数を使用する代わりにジェネレーターを返します。Motor は、yield を通じて非同期的に実装します (そうでない場合は、コールバック関数を返す必要があります)。実際、この例ではブロッキングの問題が反映されていません。時間が短すぎるため、
コードを変更しましょう
# 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)
登録ページに登録した後、ブロック期間中に /auth/login をクリックしたことがわかります。ログイン ページに直接アクセスして、ノンブロッキング プロセスを完了しました。
非同期リダイレクトの問題
トルネード問題を使用するときによく遭遇する問題です。遭遇した問題と解決策を書き留めておきます (協力してくれた Pythonistas に感謝します)私の疑問に答えます)
1. 問題
# 之前 yield self.db.user.insert(data) # 之后 yield tornado.gen.Task(tornado.ioloop.IOLoop.instance().add_timeout, time.time() + 10)ユーザーが認証コードを間違って入力した場合に登録ページにジャンプしたいのですが、問題は、認証コードが間違っていると、self.redirect の後に self.finish を追加しても実行され続けることです。 self.redirect 関数には既に self.finish があるため、コードが終了します。
上記の理由により、コードは終了しません。検証コードが間違っていると、ユーザーはエラーを返します。
2. 解決策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('/')または
return self.redirect('/auth/register')
self.finish の熱心なユーザー rsj217 によって与えられた回答は、リクエストをオフにします。 @tornado.web.aynchronous は、常にリクエスト (長いリンク) を待機することを tornado に指示するためです。 self.redirect は、応答ヘッダーの location 属性の設定と同じです
(2) 熱心なユーザー Evian からの回答。もちろん、segmentdefault の
self.finish は関数から飛び出すことはありません。それ以外の場合、リクエストが完了した後でも何かをしたい場合はどうすればよいでしょうかself. redirect はジャンプのための request.headers の場所を設定します
self.finish はリクエストを閉じますが、関数からジャンプしません Python の Tornado に関するその他の関連記事はこちらデータベースへの非同期ノンブロッキング アクセスを実装するフレームワークについては、PHP 中国語 Web サイトに注意してください。