2012-04-01 3 views
7

Sono nuovo di Tornado, e al momento sto cercando di superare questo ostacolo recente. Attualmente ho definito alcune variabili del database e istanzio i gestori, le impostazioni e le informazioni sulla connessione al database quando avvio la classe Application. Ho anche una classe di base handler (denominata BaseHandler) che fornisce un'interfaccia di database semplice ad altre classi. Mi piacerebbe dividere alcune delle mie classi in altri file, e avere la maggior parte della mia logica di database in questi altri metodi di classe, e mantenere application.py per i percorsi, e istanziare queste altre classi quando necessario, e passare i dati necessari a loro per il database. Come potrei accedere a questa funzione self.db da questi altri file/classi?Come posso accedere alle mie funzioni a livello di database all'interno di altre classi/file in 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 

Questa logica funziona bene quando non ho separato la logica in un file separato, in modo Sto chiaramente facendo qualcosa di sbagliato/manca qualcosa.

risposta

10

Ho incontrato la stessa situazione solo ora, quindi vedo alcuni esempi su github e l'ho fatto.

separo i miei file come:

  • server.py: run app
  • urls.py: definire mancini e ui_modules
  • da.py: definire metodi utili per l'accesso ai dati

Di seguito sono riportati alcuni brevi di ogni file, penso che questo possa aiutarti a risolvere il tuo problema.

urls.py

import main 
import topic 

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

ui_modules={} 

da.py

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

È possibile utilizzare db solo 'da da importa * 'e poi tutto va bene, o si può scrivere un BaseHandler estende tornado.web.RequestHandler e definire una proprietà:

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

Ogni gestore che si estende BaseHandler può utilizzare self.db per fare operazioni di database, allora.

+0

Fantastico! Grazie per la spinta nella giusta direzione, lo apprezzo. –

+0

:). Ora ho apportato alcune modifiche al mio codice. Definisco db in da.py e scrivo metodi di accesso ai dati come 'GetKindById (self, id)'. E non è necessario definire self.db in server.py, perché ogni volta che si desidera utilizzare db, è possibile importarlo da da.py o richiamare metodi come 'GetKindById (self, id)' per accedere ai dati. – goofansu

+0

È importante notare che tornado.database è stato ritirato durante i 2.4 giorni di Tornado ed è stato spostato da Tornado 3.0 a [torndb] (https://github.com/bdarnell/torndb) che non viene più mantenuto e non è compatibile con Python 3 – Marc