Examples

Momoko offers a few ways to interact with the database. The first one is the blocking client. This is just a small wrapper around Psycopg2. The other two are asynchronous clients. The example code can be found on Github. Only relevant code is shown on this page.

Blocking

The blocking client:

class BaseHandler(tornado.web.RequestHandler):
    @property
    def db(self):
        # Create a database connection when a request handler is called
        # and store the connection in the application object.
        if not hasattr(self.application, 'db'):
            self.application.db = momoko.BlockingClient({
                'host': 'localhost',
                'database': 'momoko',
                'user': 'frank',
                'password': '',
                'min_conn': 1,
                'max_conn': 20,
                'cleanup_timeout': 10
            })
        return self.application.db


class SingleQueryHandler(BaseHandler):
    def get(self):
        # Besides using a with statement everyting is the same as the normal
        # Psycopg2 module
        with self.db.connection as conn:
            cursor = conn.cursor()
            cursor.execute('SELECT 42, 12, 40, 11;')

        self.write('Query results: %s' % cursor.fetchall())
        self.finish()

Callback

The asynchronous client that uses callbacks:

class BaseHandler(tornado.web.RequestHandler):
    @property
    def db(self):
        # Create a database connection when a request handler is called
        # and store the connection in the application object.
        if not hasattr(self.application, 'db'):
            self.application.db = momoko.AsyncClient({
                'host': 'localhost',
                'database': 'momoko',
                'user': 'frank',
                'password': '',
                'min_conn': 1,
                'max_conn': 20,
                'cleanup_timeout': 10
            })
        return self.application.db


class SingleQueryHandler(BaseHandler):
    @tornado.web.asynchronous
    def get(self):
        # One simple query
        self.db.execute('SELECT 42, 12, 40, 11;', callback=self._on_response)

    def _on_response(self, cursor):
        self.write('Query results: %s' % cursor.fetchall())
        self.finish()


class BatchQueryHandler(BaseHandler):
    @tornado.web.asynchronous
    def get(self):
        # These queries are executed all at once and therefore they need to be
        # stored in an dictionary so you know where the resulting cursors
        # come from, because they won't arrive in the same order.
        self.db.batch({
            'query1': ['SELECT 42, 12, %s, %s;', (23, 56)],
            'query2': 'SELECT 1, 2, 3, 4, 5;',
            'query3': 'SELECT 465767, 4567, 3454;'
        }, self._on_response)

    def _on_response(self, cursors):
        for key, cursor in cursors.items():
            self.write('Query results: %s = %s<br>' % (key, cursor.fetchall()))
        self.finish()


class QueryChainHandler(BaseHandler):
    @tornado.web.asynchronous
    def get(self):
        # Execute a list of queries in the order you specified
        self.db.chain((
            ['SELECT 42, 12, %s, 11;', (23,)],
            'SELECT 1, 2, 3, 4, 5;'
        ), self._on_response)

    def _on_response(self, cursors):
        for cursor in cursors:
            self.write('Query results: %s<br>' % cursor.fetchall())
        self.finish()

Tornado’s gen

And the asynchronous callback-based client using Tornado’s gen module:

from tornado import gen

class BaseHandler(tornado.web.RequestHandler):
    @property
    def db(self):
        # Create a database connection when a request handler is called
        # and store the connection in the application object.
        if not hasattr(self.application, 'db'):
            self.application.db = momoko.AsyncClient({
                'host': 'localhost',
                'database': 'momoko',
                'user': 'frank',
                'password': '',
                'min_conn': 1,
                'max_conn': 20,
                'cleanup_timeout': 10
            })
        return self.application.db


class SingleQueryHandler(BaseHandler):
    @tornado.web.asynchronous
    @gen.engine
    def get(self):
        # One simple query
        cursor = yield gen.Task(self.db.execute, 'SELECT 42, 12, %s, 11;', (25,))
        self.write('Query results: %s' % cursor.fetchall())
        self.finish()


class BatchQueryHandler(BaseHandler):
    @tornado.web.asynchronous
    @gen.engine
    def get(self):
        # These queries are executed all at once and therefore they need to be
        # stored in an dictionary so you know where the resulting cursors
        # come from, because they won't arrive in the same order.
        cursors = yield gen.Task(self.db.batch, {
            'query1': ['SELECT 42, 12, %s, %s;', (23, 56)],
            'query2': 'SELECT 1, 2, 3, 4, 5;',
            'query3': 'SELECT 465767, 4567, 3454;'
        })

        for key, cursor in cursors.items():
            self.write('Query results: %s = %s<br>' % (key, cursor.fetchall()))
        self.finish()


class QueryChainHandler(BaseHandler):
    @tornado.web.asynchronous
    @gen.engine
    def get(self):
        # Execute a list of queries in the order you specified
        cursors = yield gen.Task(self.db.chain, (
            ['SELECT 42, 12, %s, 11;', (23,)],
            'SELECT 1, 2, 3, 4, 5;'
        ))

        for cursor in cursors:
            self.write('Query results: %s<br>' % cursor.fetchall())
        self.finish()


class MultiQueryHandler(BaseHandler):
    @tornado.web.asynchronous
    @gen.engine
    def get(self):
        cursor1, cursor2, cursor3 = yield [
            gen.Task(self.db.execute, 'SELECT 42, 12, %s, 11;', (25,)),
            gen.Task(self.db.execute, 'SELECT 42, 12, %s, %s;', (23, 56)),
            gen.Task(self.db.execute, 'SELECT 465767, 4567, 3454;')
        ]

        self.write('Query 1 results: %s<br>' % cursor1.fetchall())
        self.write('Query 2 results: %s<br>' % cursor2.fetchall())
        self.write('Query 3 results: %s' % cursor3.fetchall())

        self.finish()


class CallbackWaitHandler(BaseHandler):
    @tornado.web.asynchronous
    @gen.engine
    def get(self):

        self.db.execute('SELECT 42, 12, %s, 11;', (25,),
            callback=(yield gen.Callback('q1')))
        self.db.execute('SELECT 42, 12, %s, %s;', (23, 56),
            callback=(yield gen.Callback('q2')))
        self.db.execute('SELECT 465767, 4567, 3454;',
            callback=(yield gen.Callback('q3')))

        cursor1 = yield gen.Wait('q1')
        cursor2 = yield gen.Wait('q2')
        cursor3 = yield gen.Wait('q3')

        self.write('Query 1 results: %s<br>' % cursor1.fetchall())
        self.write('Query 2 results: %s<br>' % cursor2.fetchall())
        self.write('Query 3 results: %s' % cursor3.fetchall())

        self.finish()

Momoko

An asynchronous Psycopg2 wrapper for Tornado.

Table Of Contents

Previous topic

Installation

Next topic

API

This Page

Quick search

Enter search terms or a module, class or function name.


© Copyright 2011, Frank Smit.

}