Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django multi-database routing

Tags:

python

django

I have been using manual db selection to cope with a project which has two seperate dbs. I have defined my databases in the settings.

After some further reading it seems that database routing is actually the way to go with this. However, after reading the docs and some relevant posts here I am more confused than ever.

In my settings I have:

DATABASES = {     'default': {        ....      },     'my_db2': {        ....     } }  DATABASE_ROUTERS = ['myapp2.models.MyDB2Router',] 

I know I have to define my router class (I think in myapp2.models.py file) like so:

class MyDB2Router(object): """A router to control all database operations on models in the myapp2 application"""  def db_for_read(self, model, **hints):     if model._meta.app_label == 'myapp2':         return 'my_db2'     return None  def db_for_write(self, model, **hints):     if model._meta.app_label == 'myapp2':         return 'my_db2'     return None  def allow_relation(self, obj1, obj2, **hints):     if obj1._meta.app_label == 'myapp2' or obj2._meta.app_label == 'myapp2':         return True     return None  def allow_syncdb(self, db, model):      if db == 'my_db2':         return model._meta.app_label == 'myapp2'     elif model._meta.app_label == 'myapp2':         return False     return None 

Then what? Does each model require a meta.app_label or is that automatic? Aside from that, I still get an error:

django.core.exceptions.ImproperlyConfigured: Error importing database router JournalRouter: "cannot import name connection

Can anyone help me understand what is happening and what is going wrong? Any help much appreciated.

like image 625
Darwin Tech Avatar asked Nov 08 '11 16:11

Darwin Tech


People also ask

Can Django connect to multiple databases?

Django's admin doesn't have any explicit support for multiple databases. If you want to provide an admin interface for a model on a database other than that specified by your router chain, you'll need to write custom ModelAdmin classes that will direct the admin to use a specific database for content.

What is using self _DB in Django?

This is used in case you have multiple databases by which you define which database you need to use for operation. Behind the scene self.


2 Answers

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.

like image 196
Darwin Tech Avatar answered Sep 24 '22 04:09

Darwin Tech


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.

like image 36
Zakum Avatar answered Sep 22 '22 04:09

Zakum