[Django]-Django multi-database routing

31👍

OK, so I just solved my own problem. The router class goes into a separate file called routers.py under /myapp2. No meta.app_label is required as I guess it is automatically assigned. Hope this helps someone. I have also documented the process here.

6👍

Did not help me, so I did some debugging. Maybe the results can save someone some pain. 🙂
The problem in django 1.4 is a circular reference that occurs when django tries to import the custom router class.
This happens in django.db.utils.ConnectionRouter. In my case the app’s __init__.py imported a module (tastypie.api to be precise) that in turn (and through a long chain) imported django.db.models. That is not bad in itself, but models tries to import connection from django.db and that happens to have a dependency on ConnectionRouter. Which is exactly where our journey started. Hence the error.

This is described as a bug in django < 1.6 here: https://code.djangoproject.com/ticket/20704 and there is a nice small changeset thats supposed to fixed it in django 1.6:https://github.com/django/django/commit/6a6bb168be90594a18ab6d62c994889b7e745055

My solution however was to simply move routers.py from the app directory to the project directory. No nasty dependencies there.

👤Zakum

4👍

One more mistake to ommit, is to import the models in the router, this will lead to the same error, even if the router is defined in a different file.

3👍

If you have one app that uses multiple databases you can route on a per application and per table basis. For example if your app is “console” and you only want the “PoolServers” model to come from a different back end you would put this in your routers.py

class PoolServerRouter(object): 
def db_for_read(self, model, **hints):
    "Point only reads to poolserver  model to 'hamburger'"
    if model._meta.app_label == 'console' and model._meta.db_table == 'PoolServers':
        return 'hamburger'
    return 'default'

Leave a comment