Search code examples
django-modelsmultiple-databasesmakemigrations

Running manage.py makemigrations for multiple databases in django


I'm trying to use multiple databases in my Django project i.e. MongoDB and MySQL.

# settings.py
DATABASES = {
    'default': {
        'NAME': 'sql_db',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'root',
        'PASSWORD': 'root'
    },
   'mongoproject': {
      'ENGINE' : 'djongo',
      'NAME': 'mongo_db'
   }
}

I create my model for eg

# App/models.py
class ForSQL(models.Model):
    Name = models.CharField(max_length=50)
    City = models.CharField(max_length=50)

I want to save it in MySQL. For that, I will run manage.py makemigrations and then manage.py migrate. It will save in MySQL.

But when I add one more table in models.py file like:

# App/models.py
class Mongo(models.Model):
    Name = models.CharField(max_length=50)
    City = models.CharField(max_length=50)

I want to save this table in MongoDB. If I run manage.py makemigrations and then run manage.py migrate --database=mongoproject, it saves 'Mongo' Table in MongoDB and also saves 'ForSQL' table in MongoDB because of previous migrations.

I need help in setting routers for differentiating migrations on each table. I looked for this solution but can't get them working.


Solution

  • Here's how I solved my problem

    # routers.py
    import App.models
    allmodels = dict([(name.lower(), cls) for name, cls in App.models.__dict__.items() if isinstance(cls, type)])
    
    def allow_migrate(self, db, app_label, model_name = None, **hints):
        """ migrate to appropriate database per model """
        try:
            model = allmodels.get(model_name)
            return(model.params.db == db)
        except:
            pass
    
    # App/models.py
    class ForSQL(models.Model):
        class params:
            db = 'default'
        Name = models.CharField(max_length=50)
        City = models.CharField(max_length=50)
    
    class Mongo(models.Model):
        class params:
            db = 'mongoproject'
        Name = models.CharField(max_length=50)
        City = models.CharField(max_length=50)
    

    Then simply run commands manage.py makemigrations and manage.py migrate --database=default for default database (in my case MySQL) and manage.py migrate --database=mongoproject for MongoDB. It will save ForSQL table in MySQL and Mongo table in MongoDB.

    This is what I exactly needed. Hope it will help someone.

    Here it is what helped me https://stackoverflow.com/a/60453322/12134251