I've been trying to setup Django 1.4.3 to use multiple DBs, but for the life of me I can't make it to work. I read the documentation and posts on SO, and did the following:
1) Add a second DB configuration in settings.py
, as follows:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': '/tmp/django.db',
'USER': '',
'PASSWORD': '',
'HOST': '',
'PORT': '',
},
'db1' : {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db1',
'USER': 'fake',
'PASSWORD': 'fake',
'HOST': 'fake.host.com',
'PORT': '3306',
},
}
2) Create a routers.py
and define a DB router as follows
(Note: According to SO posts, if you define a DB router in models.py
, the router will not work)
class DBRouter(object):
def db_for_read(self, model, **hints):
return 'db1'
def db_for_write(self, model, **hints):
return 'db1'
def allow_syncdb(self, db, model):
return 'db1'
3) Add the following lines to settings.py
(Note: According to SO posts, these lines must be AFTER the DATABASES
configurations
from django.db import connections
DATABASE_ROUTERS = ['fakeproject.routers.DBRouter',]
This was wrong. Do NOT put from django.db import connections
here as it prevents the router to be registered
My symptoms:
Apparently, all my calls are routed through the default DB. Details below:
Both DB settings work (I can perform
manage.py indpectdb --database db1
successfullyDATABASE_ROUTERS
setting does not generate any complains (even if I put a wrong path to the DB router, or even a non-string object)When I attempt to access my objects via
manage.py shell
, I can doMyModel.objects.all()
but when I actually try to iterate it, I'm toldno such table
. The default DB does not have that table, but 'db1' clearly has it as I generated the model by usinginspectdb
on it. As a proof, if I swap the DB configuration betweendb1
anddefault
, I can access the object without problems.
Any help highly appreciated!
I think the problem is probably arising because your
routers.py
only returns a reference to'db1'
but as you say you're only being routed to'default'
I'm unsure (I would expect it to be the only routed to'db1'
.In
routers.py
create a master router class, and then subclass for each DB - and initialise with anapp_label
string so you can set them apart.and then in your
settings.py
declare the routersofcourse, you'll probably want to set up your
MasterRouter
class overrides differently.I found out that the statement in step 3 "
from django.db import connections
" was preventing the DB router to be registered. When I removed this statement, the router was registered and stuff started to work as expected.