Django how to create, update and keep clone objects to another database for backup purpose?

Viewed 91

postgresql is my primary data base. If any object create in my original database then I want it will also keep an duplicate object in my secondary database. I read Django documentation for create an clone database but didn't work. here is my code:

#replicarouter.py

 class PrimaryReplicaRouter:
    def db_for_read(self, model, **hints):
        """
        Reads go to a randomly-chosen replica.
        """
        return 'primary'

    def db_for_write(self, model, **hints):
        """
        Writes always go to primary.
        """
        return 'primary'

    def allow_relation(self, obj1,**hints):
        """
        Relations between objects are allowed if both objects are
        in the primary/replica pool.
        """
        db_set = {'primary', 'replica_database'}
        if obj1._state.db in db_set:
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        """
        All non-auth models end up in this pool.
        """
        return True
 

settings.py

     DATABASES = {
        'default':{},
        'primary': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': 'my_db_name',
            'USER': 'postgres',
            'PASSWORD': 'my_db_pass',
            'HOST': 'localhost',
            'PORT':5432,
        },

        'replica_database': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'my_db_name',
            'USER': 'root',
            'PASSWORD': '',
            'HOST': 'localhost',
            'PORT': 3306,
        }

        
    }

DATABASE_ROUTERS = ['my_root_folder_name.dbrouters.AuthRouter','my_root_folder_name.replicarouter.PrimaryReplicaRouter']

right now all new objects creating in my primary database. I want to keep clone of every new object in my replica_database. If any object added in my primary database then it will also add an clone object in my replica_database.

1 Answers

finally I find out an solution. After reading django multiple database documentation we can use multiple database but can't keep clone object in our database. Let explain little bit assume you have two model teacher and student. You can use two separate database for teacher and student but you can't use another database for keep clone objects of your teacher and student model. So here we will use django siganls for keep clone objects in our replica_database. Signals will be triggered and create clone object whenever any objects create in our model. Here is my code:

settings.py

'default': { 
        'NAME': 'primary_database',
        'ENGINE': 'django.db.backends.mysql',
        'HOST': 'localhost',
        'USER': 'root',
        'PASSWORD': '',
    },
    'replica1_database': {
        'NAME': 'replica1_database',
        'ENGINE': 'django.db.backends.mysql',
        'HOST': 'localhost',
        'USER': 'root',
        'PASSWORD': '', },

models.py:

from django.db.models.signals import post_save
from django.dispatch import receiver

class Contact(models.Model):
      name = models.CharField(blank=True, null=True, max_length=100)
    
    
@receiver(post_save, sender=Contact, dispatch_uid="clone_objects")
def replica1_databse(sender, instance, created, **kwargs):
    if created: #cerate clone object in our replica1 database
         obj = instance
         obj.save(using='replica1') 
    else: #updating clone object in our replica1 database
         obj = Contact.objects.using('replica1').update(
         name=instance.name)

Here I am triggering signals for create an clone objects in my replica1_database.

Now run python manage.py makemigrtions contact and python manage.py migrate contact this two migrations applied in your default database. This is the most important step ----> You have to run python manage.py migrate --database=replica1 This migrate applied for your replica1 database.

I Think it also an good idea to keep an backup database for avoid any unexcepted situation such as server down.

Related