使用django中的信号设置数据库复制(仅添加/更新/删除数据)

问题描述 投票:0回答:2

我不想使用数据库的内置功能进行复制。所以我试图在add应用程序级别设置数据库复制(updatedeletedjnago操作)。 我在multi-db配置了settings.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

我的要求是保持两个数据库同步(它们应该具有相同的数据)。我想使用像signalsdjango.db.models.signals.post_save这样的djnago django.db.models.signals.post_delete保持两个数据库同步

例如,如果我正在运行

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

然后这样的条目也应该在其他数据库中创建。 如何写receiver function来处理这些信号?我应该在哪里保留接收器功能?

python django postgresql database-replication django-signals
2个回答
0
投票

您应该在数据库级别配置数据库复制。

这更可靠,因为postgresql是为此目的而制作的。您可以在此链接中找到更多信息:https://www.postgresql.org/docs/10/high-availability.html


0
投票

我们需要创建相关信号的适当接收函数。有些是由django本身提供的,有些是在外部模块Django Query Signals中提供的

因此在app目录中创建了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_signalsINSTALLED_APPS中添加settings.py

© www.soinside.com 2019 - 2024. All rights reserved.