4

I have two models in my django app and I want their tables/databases to be stored in seperate db/sqlite3 files rather than in the default 'db.sqlite3' file.



Eg:
my models.py has two classes Train and Bus, I want them to be stored in train.db and bus.db

4
  • the relevant question I found was: (stackoverflow.com/questions/16573108/…) But, I need an example of what to write in models.py, settings.py and any other file that I need to write Commented Apr 24, 2015 at 6:41
  • What is the reason for storing them in separate files? Are you aware of the limitations of using multiple databases? Commented Apr 24, 2015 at 7:30
  • I'm aware of that. What I really want to do is to create archive files. As in when I'm generating report in my program at the end of each month I want the table data to be stored in a separate file so that when there is some sort of corrupt in writing data to the file. I don't loose the old one. Saving everything to one file makes it huge and vulnerable. Commented Apr 24, 2015 at 7:54
  • 1
    Is it not sufficient to configure your DATABASES setting with multiple databases, with different 'NAME' values, then create a database router which routes dependent on the model name? The example in the docs should get you most of the way there. Commented May 6, 2015 at 16:06

1 Answer 1

12
+50

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)

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for putting in the work for the code sample. :) This is precisely what I had in mind.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.