Banana and multiple databases

The way we deploy TRAP and Banana at the University of Amsterdam is that various scientists create multiple PostgreSQL and MonetDB databases and populate these with data. We want to be able to visualise the content of all these databases.

We’ve created various helper functions (project.settings.database) that assist in automatically populating the Django configuration with our site specific configuration. It is adviced not to use these in production, but rather build a manual configuration.

The database which is used is based on the URL, specifically the URL variable. We’ve crafted a combination of Django middleware and Django database routing that makes Django use the desired database. Below is the module documentation for that logic.

Module documentation

Select database based on URL variable

Inspired by this Django snipped.

It’s assumed that any view in the system with a cfg keyword argument passed to it from the urlconf may be routed to a separate database. for example:

url( r'^(?P<db>\w+)/account/$', 'views.account' )

The middleware and router will select a database whose alias is <db>, default if no db argument is given and raise a 404 exception if not listed in settings.DATABASES, all completely transparent to the view itself.

class project.multidb.MultiDbRouter[source]

The multiple database router.

Add this to your Django database router configuration, for example:

DATABASE_ROUTERS += ['project.multidb.MultiDbRouter']
class project.multidb.MultiDbRouterMiddleware[source]

The Multidb router middelware.

he middleware process_view (or process_request) function sets some context from the URL into thread local storage, and process_response deletes it. In between, any database operation will call the router, which checks for this context and returns an appropriate database alias.

Add this to your middleware, for example:

MIDDLEWARE_CLASSES += ['project.multidb.MultiDbRouterMiddleware']
project.multidb.multidb_context_processor(request)[source]

This context processor will add a db_name to the request.

Add this to your Django context processors, for example:

TEMPLATE_CONTEXT_PROCESSORS +=[
    'project.multidb.multidb_context_processor']