我已经在Django中实现了Automatic DB Routing,并使用了AWS Aurora for Database进行复制。我发现我的数据库存在较小的复制滞后,从而阻碍了流程。比方说,发生问题的原因是,当读取的查询集正在以“从属”执行时,然后在使用该查询集更新值时显示错误,例如“对该表的只读访问”。这意味着要进行更新,它应该路由到主数据库。
这是我的多个数据库的数据库设置:
DATABASES = {
'master': {
'ENGINE': 'django.db.backends.mysql',
'STORAGE_ENGINE': 'MyISAM / INNODB / ETC',
'NAME': 'db',
'USER': 'master',
'PASSWORD': 'master',
'HOST': 'localhost',
'PORT': '3306',
},
'slave': {
'ENGINE': 'django.db.backends.mysql',
'STORAGE_ENGINE': 'MyISAM / INNODB / ETC',
'NAME': 'db',
'USER': 'name',
'PASSWORD': 'pass',
'HOST': 'localhost',
'PORT': '3306',
},
'slave2': {
'ENGINE': 'django.db.backends.mysql',
'STORAGE_ENGINE': 'MyISAM / INNODB / ETC',
'NAME': 'db',
'USER': 'name',
'PASSWORD': 'pass',
'HOST': 'localhost',
'PORT': '3306',
}
}
DATABASE_ROUTERS = ['path.to.AuthRouter']
请提供给我最好的方式来自动处理Django中的多个数据库路由。
"""
DB Router core class which auto selects required database configuration
"""
class AuthRouter:
def db_for_read(self, model, **hints):
"""
Reads go to a replica.
"""
print 'db_for_read'
print model
return 'slave'
def db_for_write(self, model, **hints):
"""
Writes always go to master ie default.
"""
print 'db_for_write'
print model
return 'master'
def allow_relation(self, obj1, obj2, **hints):
"""
Relations between objects are allowed if both objects are
in the default/replica pool.
"""
db_list = ('master', 'slave')
if obj1._state.db in db_list and obj2._state.db in db_list:
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
答案 0 :(得分:0)
您可以拆分读取操作并隔离主数据库的写入操作,例如: AuthRouter应该调用主数据库,因为这是用户的最新信息。
class AuthRouter:
def db_for_read(self, model, **hints):
"""
Reads go to a replica.
"""
return 'master'
def db_for_write(self, model, **hints):
"""
Writes always go to master ie default.
"""
return 'master'
def allow_relation(self, obj1, obj2, **hints):
"""
Relations between objects are allowed if both objects are
in the default/replica pool.
"""
db_list = ('master', 'slave')
if obj1._state.db in db_list and obj2._state.db in db_list:
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
class PrimaryReplicaRouter(object):
"""
A router to control all read/write database operations.
"""
def db_for_read(self, model, **hints):
"""
Reads go to a randomly-chosen replica.
"""
return select_rand_db()
def db_for_write(self, model, **hints):
"""
Writes always go to primary.
"""
return 'master'
def allow_relation(self, obj1, obj2, **hints):
"""
Relations between objects are allowed if both objects are
in the primary/replica pool.
"""
return True
def allow_migrate(self, db, app_label, model_name=None, **hints):
"""
All non-auth models end up in this pool.
"""
return True
def select_rand_db():
from numpy.random import choice
"""
this function returns rand db or default if running tests
:return:
"""
return choice(['master', 'slave'], p=[0.5, 0.5])