Настройка репликации базы данных (добавление / обновление / удаление только данных) с использованием сигналов в django - PullRequest
0 голосов
/ 06 февраля 2019

Я не хочу использовать встроенные функции базы данных для репликации.Поэтому я пытаюсь настроить репликацию базы данных (только операции add, update, delete) на уровне приложения djnago .
Я настроил multi-dB insettings.py

Таким образом, файл настроек выглядит как

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': config['DB_NAME'],
        'USER': config['DB_USER'],
        'PASSWORD': config['DB_PASSWORD'],
        'HOST': config['DB_HOST'],
        'PORT': config['DB_PORT'],
    },
    'tableau': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'tableau',
        'USER': 'postgres',
        'PASSWORD': 'postgres',
        'HOST': 'localhost',
        'PORT': 5432,
    },
}

Я могу читать и писать из обеих баз данных, например

from myapp.model import People

# writing to db
People.objects.create(name='alok', location='India') # onto defalut db
People.objects.using('tableau').create(name='alok', location='India') # onto replication db

# reading from db
People.objects.filter(name='alok') # from default db
People.objects.using('tableau').filter(name='alok') # from replication db

Мне необходимо сохранить обе базы данныхсинхронно (они должны иметь одинаковые данные).Я хочу синхронизировать обе базы данных, используя сигналы djnago вроде django.db.models.signals.post_save и django.db.models.signals.post_delete

Например, если я запускаю

People.objects.create(name='alok2', location='India2')

Тогда такая запись должнасоздать в другой базе данных также.
Как написать функцию приемника для обработки этих сигналов?И где я должен сохранить эту функцию приемника?

Ответы [ 2 ]

0 голосов
/ 13 февраля 2019

Нам нужно создать правильную функцию приемника соответствующих сигналов.Некоторые из них предоставляются самим django, а некоторые доступны во внешнем модуле Сигналы запросов Django

Таким образом, создано signals.py в каталоге приложения, чтобы сохранить все функции приемника.

from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from django_query_signals import post_update, post_bulk_create, post_get_or_create, post_update_or_create


@receiver(post_save)
def post_save_receiver(sender, instance, created, raw, using, **kwargs):
    if using == 'default':
        instance.save(using='tableau')


@receiver(post_delete)
def post_delete_receiver(sender, instance, using, **kwargs):
    if using == 'default':
        instance.delete(using='tableau')


@receiver(post_update)
def post_update_receiver(*args, **kwargs):
    received_call = kwargs['args']
    db_name = received_call['self']._db
    method = received_call['method']
    if db_name == None and method == 'update':
        received_query_set = received_call['self']
        received_query_set.using('tableau').update(**received_call['kwargs'])


@receiver(post_bulk_create)
def post_bulk_create_receiver(*args, **kwargs):
    received_call = kwargs['args']
    db_name = received_call['self']._db
    method = received_call['method']
    if db_name == None and method == 'bulk_create':
        sender = kwargs['sender']
        objs = received_call['objs']
        batch_size = kwargs['args']['batch_size']
        sender.objects.using('tableau').bulk_create(objs, batch_size=batch_size)


@receiver(post_get_or_create)
def post_get_or_create_receiver(*args, **kwargs):
    received_call = kwargs['args']
    db_name = received_call['self']._db
    method = received_call['method']
    if db_name == None and method == 'get_or_create':
        sender = kwargs['sender']
        obj = received_call['kwargs']
        defaults = received_call['defaults']
        sender.objects.using('tableau').get_or_create(**obj, defaults=defaults)


@receiver(post_update_or_create)
def post_update_or_create_receiver(*args, **kwargs):
    received_call = kwargs['args']
    db_name = received_call['self']._db
    method = received_call['method']
    if db_name == None and method == 'update_or_create':
        sender = kwargs['sender']
        obj = received_call['kwargs']
        defaults = received_call['defaults']
        sender.objects.using('tableau').update_or_create(**obj, defaults=defaults)

Добавить запись для регистрации этих функций приемника в my_django_project/my_app/apps.py

from django.apps import AppConfig

class MyAppConfig(AppConfig):
    name = 'my_app'

    def ready(self):
        import my_app.signals # this will load receiver functions

Добавить MyAppConfig запись в my_django_project/my_app/__init__.py

default_app_config = 'my_app.apps.MyAppConfig'

И, конечно,вам нужно добавить django_query_signals в INSTALLED_APPS в settings.py

0 голосов
/ 06 февраля 2019

Вероятно, вам следует настроить репликацию базы данных на уровне базы данных.

Это более надежно, поскольку для этой цели создан postgresql.Вы найдете больше информации по этой ссылке: https://www.postgresql.org/docs/10/high-availability.html

...