[Django]-Single django app to use multiple sqlite3 files for database

12👍

Of course you could always just use Train.objects.using('train') for your calls and that would select the correct database (assuming you defined a database called train in your settings.py.

If you don’t want to do that, I had a similar problem and I adjusted my solution to your case. It was partially based on this blog article and the Django documentation for database routers is here.

With this solution your current database will not be affected, however your current data will also not be transferred to the new databases. Depending on your version of Django you need to either include allow_syncdb or the right version of allow_migrate.

In settings.py:

DATABASES = {
     'default': {
         'NAME': 'db.sqlite3',
         'ENGINE': 'django.db.backends.sqlite3',
     },
     'train': {
         'NAME': 'train.db',
         'ENGINE': 'django.db.backends.sqlite3',
     },
     'bus': {
         'NAME': 'bus.db',
         'ENGINE': 'django.db.backends.sqlite3',
     },
}


DATABASE_ROUTERS = [ 'yourapp.DatabaseAppsRouter']

DATABASE_APPS_MAPPING = {'train': 'train', 'bus': 'bus'}

In a new file called database_router.py:

from django.conf import settings

class DatabaseAppsRouter(object):
    """
    A router to control all database operations on models for different
    databases.

    In case an app is not set in settings.DATABASE_APPS_MAPPING, the router
    will fallback to the `default` database.

    Settings example:

    DATABASE_APPS_MAPPING = {'model_name1': 'db1', 'model_name2': 'db2'}

    """

    def db_for_read(self, model, **hints):
        """Point all read operations to the specific database."""
        return settings.DATABASE_APPS_MAPPING.get(model._meta.model_name, None)

    def db_for_write(self, model, **hints):
        """Point all write operations to the specific database."""
        return settings.DATABASE_APPS_MAPPING.get(model._meta.model_name, None)

    def allow_relation(self, obj1, obj2, **hints):
        """Have no opinion on whether the relation should be allowed."""
        return None

    def allow_syncdb(self, db, model): # if using Django version <= 1.6
        """Have no opinion on whether the model should be synchronized with the db. """
        return None

    def allow_migrate(db, model): # if using Django version 1.7
        """Have no opinion on whether migration operation is allowed to run. """
        return None

    def allow_migrate(db, app_label, model_name=None, **hints): # if using Django version 1.8
        """Have no opinion on whether migration operation is allowed to run. """
        return None

(Edit: this is also what Joey Wilhelm suggested)

👤sykaeh

Leave a comment