我不想使用数据库的内置功能进行复制。因此,我试图在djnago应用程序级别上设置数据库复制(仅add
,update
,delete
操作)。
我已经在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
我的要求是使两个数据库保持同步(它们应该具有相同的数据)。我想使用django.db.models.signals.post_save
和django.db.models.signals.post_delete
例如,如果我在跑步
People.objects.create(name='alok2', location='India2')
然后,此类条目也应在其他数据库中创建。
如何编写receiver function来处理这些信号?我应该在哪里保留接收器功能?
答案 0 :(得分:0)
您可能应该在数据库级别配置数据库复制。
这是更可靠的,因为postgresql是为此目的而制作的。 您将在此链接上找到更多信息: https://www.postgresql.org/docs/10/high-availability.html
答案 1 :(得分:0)
我们需要创建适当的相关信号接收器功能。有些是由django本身提供的,有些是在外部模块Django Query Signals
中可用的因此在应用目录中创建了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
的{{1}}中添加INSTALLED_APPS