Tips for setting up multiple databases routing in Django

149 views
Skip to first unread message

Jim

unread,
Aug 24, 2011, 8:33:02 PM8/24/11
to django...@googlegroups.com
First of all, I would like to thank Reinout van Rees (http://reinout.vanrees.org/) for his helpful suggestions. 

Suppose you have two databases, 'default' and 'test', and one app, 'books'. And you want to store the models in books in the database 'test'. 

According to the guide from Django doc, you may have something like this in your settings.py:
<code>
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': '/path/to/default.sqlite',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
    },
    'test': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': '/path/to/test.sqlite',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': '',
    }
}
</code>

And a routing file, say dbrouting.py, which has something like this:
<code>
class DBRouter(object):
    def db_for_read(self, model, **hints):
        label = model._meta.app_label
        if label == 'books':
            dbName = 'test' # dbName is a name in settings.DATABASES
        else:
            dbName = None
        return dbName

    def db_for_write(self, model, **hints):
        label = model._meta.app_label
        if label == 'books':
            dbName = 'test'
        else:
            dbName = None
        return dbName

    def allow_relation(self, obj1, obj2, **hints):
        label1 = obj1._meta.app_label
        label2 = obj2._meta.app_label
        if label1 == label2:
            return True
        return None

    def allow_syncdb(self, db, model):
        # db is a string of database name.
        label = model._meta.app_label
        if label == 'books':
            dbName = 'test'
        else:
            dbName = None
        if dbName == db:
            return True
        else:
            return False
</code>

Now, here is the important stuff. If you don't have the database file test.sqlite yet, you must create it first before you enable the database routing. Use the following command to do this:
<code>
./manage.py syncdb --database=test
</code>
With this step, Django will initialize the database, including creating some required tables (such as django_content_type). In the routing scheme, only models from the app books can access the database 'test'. That means that even Django cannot get in the database and make the necessary setups including creating some necessary tables. Once you have initialized the database, you can enable the routing scheme.

To sum up, here are the steps I recommend if you want to create a database to store data from certain models.
  1. Add that new database to settings.py.
  2. Make sure that the database routing is disabled. (To disable the database routing, just comment out the DATABASE_ROUTERS setting in the settings.py file.)
  3. Initialize your new database as shown above.
  4. Enable database routing (by enabling the DATABASE_ROUTERS setting in the settings.py file).
  5. Run <code>./manage.py syncdb --database=<dbname></code> to create tables for your models.
In the above steps, I assume you have created your models and database routers properly.

That's it.

BTW, I am new to Django. So, if I am missing anything above or having anything misleading, please do correct me. Thank you very much.
 



Reply all
Reply to author
Forward
0 new messages