Как получить доступ к функциям уровня моей базы данных внутри других классов / файлов в Tornado? - PullRequest
7 голосов
/ 01 апреля 2012

Я новичок в Торнадо, и в настоящее время я пытаюсь преодолеть этот недавний камень преткновения.В настоящее время у меня определены некоторые переменные базы данных, и я создаю экземпляры обработчиков, настроек и информации о подключении к базе данных, когда запускаю класс Application.У меня также есть базовый класс обработчика (названный BaseHandler), который обеспечивает простой интерфейс базы данных для других классов.Я хотел бы разделить некоторые из моих классов на другие файлы, и большую часть своей логики базы данных использовал в этих других методах классов, а также оставлял application.py для маршрутов, создавал экземпляры этих других классов при необходимости и передавал необходимые данныеих для базы данных.Как мне получить доступ к этой функции self.db из этих других файлов / классов?

application.py:

import tornado.database
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web

from tornado.options import define, options
from user import User

# Define some startup settings, can be changed through the command line
define("port", default=8888, help="Run on the given HTTP port", type=int)
define("db_host", default="localhost:3306", help="Database host")
define("db_name", default="database_name", help="Database name")
define("db_user", default="user", help="Database username")
define("db_pass", default="password", help="Database password")

class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r"/", MainHandler)
        ]
        settings = dict(
            application_title = u"Test Application",
            template_path = os.path.join(os.path.dirname(__file__), "templates"),
            static_path = os.path.join(os.path.dirname(__file__), "static"),
            autoescape = None
        )
        tornado.web.Application.__init__(self, handlers, **settings)

        self.db = tornado.database.Connection(
            host=options.db_host, database=options.db_name,
            user=options.db_user, password=options.db_pass)

class BaseHandler(tornado.web.RequestHandler):
    @property
    def db(self):
        return self.application.db

class MainHandler(BaseHandler):
    def get(self):
        u = User()
        self.write(tornado.escape.json_encode(u.get_user("test@test.com)))

user.py:

class User(object):
    def get_user(self, email):
        result = self.db.get("SELECT first_name, last_name FROM users WHERE email = %s", email)
        if not result: return False
        return True, result

Эта логика работает нормально, когда я не выделил логику в отдельный файл, поэтому я явно что-то делаю не так / что-то упущено.

1 Ответ

10 голосов
/ 06 апреля 2012

Я сталкиваюсь с такой же ситуацией только сейчас, затем я просматриваю некоторые примеры на github и сделал это.

Я разделяю мои файлы как:

  • server.py: запустить приложение
  • urls.py: определить handers и ui_modules
  • da.py: определить полезные методы для доступа к данным

Ниже приведено краткое описание каждого файла, я думаю, что это можетпоможет вам решить вашу проблему.

urls.py

import main
import topic

handlers=[]
handlers.extend(main.handlers)
handlers.extend(topic.handlers)

ui_modules={}

da.py

import tornado.database

from tornado.options import define,options
define("mysql_host", default="127.0.0.1:3306", help="database host")
define("mysql_database", default="forum", help="database name")
define("mysql_user", default="root", help="database user")
define("mysql_password", default="111111", help="database password")

db = tornado.database.Connection(
    host=options.mysql_host, database=options.mysql_database,
    user=options.mysql_user, password=options.mysql_password)

server.py

import os
import tornado.database
import tornado.httpserver
import tornado.ioloop
import tornado.web

from tornado.options import define, options
define("port", default=8888, help="run on the given port", type=int)

import da

class Application(tornado.web.Application):
    def __init__(self):
        from urls import handlers,ui_modules
        settings = dict(
            template_path=os.path.join(os.path.dirname(__file__), "templates"),
            static_path=os.path.join(os.path.dirname(__file__), "static"),
            xsrf_cookies=True,
            cookie_secret="11oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=",
            login_url="/signin",
            ui_modules=ui_modules,
            debug=True,
        )
        super(Application,self).__init__(handlers,**settings)
#       tornado.web.Application.__init__(self, handlers, **settings)
        # Have one global connection to the blog DB across all handlers
        self.db = da.db

def runserver():
    tornado.options.parse_command_line()
    http_server = tornado.httpserver.HTTPServer(Application())
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

if __name__ == "__main__":
    runserver()

Вы можете использовать db просто 'из da import *', и тогда все будет хорошо, или вы можете написать BaseHandler, расширяет tornado.web.RequestHandler и определить свойство:

class BaseHandler(tornado.web.RequestHandler):
    @property
    def db(self):
        return self.application.db

Каждый обработчик, расширяющий BaseHandler, может использовать self.db для выполнения операций с базой данных.

...