30

I have two databases and two models:the Admin and the user.

I want to sync my models to the two databases; admin model to database A and user model to database B;

If I am setting the model path to INSTALLED_APPS and syncdb, the two models will sync to the default database.

if I set the database in the syncdb command such as sync --database="B", and the two models will sync to database B.

So my problem is, how do I sync the two models to two databases?

kuafu
  • 1,466
  • 5
  • 17
  • 28

2 Answers2

31

I fully agree with @alecxe on using the database router. I am currently using a single admin interface to manage multiple databases. Note that authentication for all databases are stored in the default database, so when you do the syncdb (with no arguments).

Generic Database Router

I found this implementation to be extremely flexible and useful.

Settings.py

# Define the database manager to setup the various projects
DATABASE_ROUTERS = ['manager.router.DatabaseAppsRouter']
DATABASE_APPS_MAPPING = {'mux_data': 't29_db', 
                         'T50_VATC':'t50_db'}

DATABASES = {
    'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2', 
            'NAME': 'fail_over',                    
            'USER': 'SomeUser',                      
            'PASSWORD': 'SomePassword',                  
            'HOST': '127.0.0.1',                     
            'PORT': '',                      
    },

    't29_db': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2', 
            'NAME': 'mux_stage',                    
            'USER': 'SomeUser',                      
            'PASSWORD': 'SomePassword',                  
            'HOST': '127.0.0.1',                      
            'PORT': '',                      
    },

    't50_db': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2', 
            'NAME': 't50_vatc',                    
            'USER': 'SomeUser',                      
            'PASSWORD': 'SomePassword',                 
            'HOST': '127.0.0.1',                     
            'PORT': '',                      
    },
}

Sample Models

# Create your models here.
class Card_Test(models.Model):
    name = models.TextField(max_length=100)
    description = models.TextField(max_length=200)
    units = models.TextField(max_length=500)
    result_tags = models.TextField(max_length=500)

    class Meta:
        app_label = 'mux_data'

    def __unicode__(self):
        return self.name

class Status_Type(models.Model):
    status = models.CharField(max_length=25)

    class Meta:
        app_label = 'mux_data'

    def __unicode__(self):
        return self.status
Adam Lewis
  • 7,017
  • 7
  • 44
  • 62
  • 1
    In both the models defined you have set the app_label to 'mux_data'. Is that intentional to show that both these models will go to database t29_db? And so if any other model has app_label 'T50_VATC', that will be saved in db t50_db. – Vikas Ojha Jun 05 '15 at 21:26
  • @VikasNehaOjha Yes that was intentional. It was to show that each model can control where it's data is stored. – Adam Lewis Jun 09 '15 at 15:40
  • Thanks. Your answer helped me. – Vikas Ojha Jun 09 '15 at 15:42
  • 4
    Where should be the class DatabaseAppsRouter? what should it import? – Kiran K Telukunta Oct 11 '16 at 16:14
  • 4
    As of today, the link is broken and the answer is not working. You should add the code directly to the answer otherwise it is not an answer anymore. – AivanF. Nov 22 '18 at 20:53
  • @AdamLewis Your link is dead by now. Add your copy please – joe Jul 18 '19 at 04:26
  • 1
    https://web.archive.org/web/20180601203243/http://www.diegobz.net/2011/02/10/django-database-router-using-settings/ – mehmetö Jan 11 '20 at 17:55
22

In order to define specific databases used for specific models, you need to define a database router:

The easiest way to use multiple databases is to set up a database routing scheme. The default routing scheme ensures that objects remain ‘sticky’ to their original database (i.e., an object retrieved from the foo database will be saved on the same database). The default routing scheme ensures that if a database isn’t specified, all queries fall back to the default database.

See this snippet as an example: http://djangosnippets.org/snippets/2687/

Also see:

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • alecxe,thx,but what the app_label?should I set the app_label in django models? – kuafu Aug 31 '13 at 11:31
  • It doesn't really matter and it depends on how you will implement your router. FYI, there is an [example in django docs](https://docs.djangoproject.com/en/dev/topics/db/multi-db/#using-routers) that shows how to use `app_label` for routing. – alecxe Aug 31 '13 at 11:35
  • in the https://thenewcircle.com/s/post/1242/django_multiple_database_support, it gives:if model._meta.app_label == 'chinook': return 'chinookdb' so if I want to a model to operate on chinookdb,I should add a app_label in the meta,right? – kuafu Aug 31 '13 at 12:40
  • @young001 yes, if you are following instructions given in this article. – alecxe Aug 31 '13 at 15:12
  • @young001, you definitely don't need to declare the app_labels in the meta classes of your models--- if the model is defined within your app directory and not externally. I have just implemented two databases, with routers, as you described, and they are working in Django 1.8 without the explicit declaration. The example presented by Adam Lewis below does not contradict this but is instead a different approach involving overriding the default use of the app name as the app_label so as to not only avoid duplicate routers but also potentially use one database for a specified two or more apps. – Mike O'Connor Sep 01 '16 at 07:50