How do I access my database level functions inside other classes/files in Tornado?

I'm new to Tornado, and I'm currently trying to get past this recent stumbling block. Currently I have some database variables defined, and I instantiate the handlers, settings, and database connection info when I init the Application class. I also have a base handler class (named BaseHandler) which provides a simple database interface to other classes. I'd like to split some of my classes into other files, and have most of my database logic in those other class methods, and keep application.py for the routes, and instantiating these other classes when needed, and passing the necessary data to them for the database. How would I access this self.db function from within these other files/classes?

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

This logic does work fine when I haven't separated the logic out to a separate file, so I'm clearly doing something wrong/missing something.

Answers


I meet the same situation just now, then I view some examples on github and made that.

I separate my files like:

  • server.py: run app
  • urls.py: define handers and ui_modules
  • da.py: define helpful methods for data access

Following are some brief of each file, I think this can help you to solve your problem.

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

You can use db just 'from da import *' and then everything goes well, or you can write a BaseHandler extends tornado.web.RequestHandler and define a property:

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

Every handler that extends BaseHandler can use self.db to do database operations then.


Need Your Help

LibGdx TouchInput gives strange numbers for position on the screen

android input libgdx

have a small problem. Cannot understand how to solve it.

How to keep multiple marker bubble info open (shown) (HERE Android SDK)

android maps here-api

I'm using HERE Android SDK and I can't seem to make multiple bubble info open. When I click on another marker and show the bubble info, the previous one is closed/hidden. I'd like to keep all the b...