2012-04-01 5 views
7

Jestem nowy w Tornado i obecnie próbuję ominąć ten ostatni blok. Obecnie mam zdefiniowane pewne zmienne bazy danych i uruchamiam procedury obsługi, ustawienia i informacje o połączeniu z bazą danych po zainicjowaniu klasy Application. Posiadam również podstawową klasę obsługi (o nazwie BaseHandler), która zapewnia prosty interfejs bazy danych dla innych klas. Chciałbym podzielić niektóre z moich klas na inne pliki i mieć większość logiki bazy danych w tych innych metodach klasy, a także zachować application.py dla tras i tworzyć instancję tych klas w razie potrzeby oraz przekazywać niezbędne dane do ich do bazy danych. Jak uzyskać dostęp do funkcji self.db z tych innych plików/klas?Jak uzyskać dostęp do funkcji poziomu bazy danych w innych klasach/plikach w Tornado?

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("[email protected]))) 

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 

Ta logika nie działa poprawnie, gdy nie oddziela logikę się do osobnego pliku, więc Wyraźnie robię coś złego/coś brakuje.

Odpowiedz

10

W tej chwili spotykam się z podobną sytuacją, a następnie przeglądam kilka przykładów na github i robię to.

oddzielić moje pliki jak:

  • server.py: Uruchom aplikację
  • urls.py: define handers i ui_modules
  • da.py: define pomocnych metod dostępu do danych

Poniżej znajduje się krótki opis każdego pliku, myślę, że może to pomóc w rozwiązaniu problemu.

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() 

Można użyć db tylko „z da import * ', a następnie wszystko idzie dobrze, czy można napisać BaseHandler rozciąga tornado.web.RequestHandler i zdefiniować właściwość:

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

Każdy obsługi, która rozciąga BaseHandler mogą korzystać self.db zrobić operacji bazodanowych wtedy.

+0

Awesome! Dzięki za popchnięcie we właściwym kierunku, doceniam to. –

+0

:). Teraz dokonałem pewnych zmian w moim kodzie. Definiuję db na da.py i zapisuję w nim metody dostępu do danych, takie jak 'GetKindById (self, id)'. I nie ma potrzeby definiowania self.db w serwerze .py, ponieważ za każdym razem, gdy chcesz użyć db, możesz zaimportować go z da.py lub wywołać metody takie jak 'GetKindById (self, id)' aby uzyskać dostęp do danych. – goofansu

+0

Należy zauważyć, że tornado.database zostało wycofane podczas Tornado 2.4 dni i zostało przeniesione z Tornado 3.0 do [torndb] (https://github.com/bdarnell/torndb), które nie jest już dłużej utrzymywane i nie jest kompatybilny z Python 3 – Marc