使用Django multidb,编写运行主/从基础结构的router相当容易。但是有可能将写入的路由器编写到多个数据库中吗?我的用例是一组项目,都在同一个域上运行。为了节省用户在每个站点上注册/登录,我想同步contrib.auth
和contrib.sessions
表。这是可能的Django multidb还是我应该研究数据库系统的复制功能(在我的情况下是MySQL)?
答案 0 :(得分:6)
我认为您将更好地实施SSO或OAuth服务
但是如果你想在两个数据库之间同步你的表用户,如果你使用自己的UserModel,你可以做这样的事情
class MyUser(models.Model):
name = models.CharField(max_length=100)
user = models.ForeignKey(User, unique=True)
def save(self, ...): # ALL the signature
super(MyUser, self).save(using='database_1')
super(MyUser, self).save(using='database_2')
你也可以使用这样的装饰器,像这样你也可以用它来同步其他表:
def save_multi_db(model_class):
def save_wrapper(save_func):
def new_save(self, *args, **kws):
super(model_class, self).save(using='database_1')
super(model_class, self).save(using='database_1')
return new_save
func = getattr(model_class, 'save')
setattr(model_class, 'save', save_wrapper(func))
return save_wrapper
# and use it like this:
@save_multi_db
class MyUser(models.Model):
....
希望这会有所帮助:)
答案 1 :(得分:4)
我正在研究Django分片架构。
我看着Django路由器,但决定推出自己的路由器。
关于你的问题的一些想法:
类似的东西 -
import settings.databases as dbs_list
def post_save_function(UserModel):
for db in dbs_list:
UserModel.save(using=db,force_insert=True)
保存用户对象(至少在单数据库模型上)似乎通过django.contrib内部发生的各种魔法保存会话,身份验证等数据,因此您可能无需进入并找出所有这些数据库表的名称和类型。
为了支持这种工作的可能性,我发誓我最近在某处读过(可能在Alex Gaynor的一篇博客文章中),如果一个对象有一个外键,Django会尝试使用该对象所在的同一个DB(用于鉴于Django通常的运作方式,显而易见的原因)。
从您引用的Django multiDB页面上的示例中我想知道以下内容是否会起作用:
他们的示例代码:
def allow_syncdb(self, db, model):
"Explicitly put all models on all databases."
return True
可能的修改:
def allow_syncdb(self,db,model):
if isinstance(model,User):
return True
elif isinstance(model,Session):
return True
else:
''' something appropriate --
whatever your sharding schema is for other objects '''
再看一遍,这段代码作为“db_for_write”函数可能会更有用。但是你明白了。
毫无疑问,您必须添加其他类型的模型才能使其工作(所有auth的东西,这是广泛的)。
祝你好运!希望这在某种程度上有所帮助。我对你的发现和评论感兴趣!
JB
答案 2 :(得分:1)
首先,我认为您需要的是更多的SSO框架,例如in this post
我尝试了mouad的答案,但我无法让类装饰工作......而且在我看来这个解决方案不允许在模型中使用自定义save()。
更适合我的需要,我已经定义了一个自定义泛型类,并简单地覆盖了save()函数。
class MultiDbModel(models.Model):
class Meta:
abstract = True
def save(self, *args, **kwarg
for dbname in settings.DATABASES:
super(MultiDbModel, self).save(using=dbname)
然后:
class MyObject(MultiDbModel):
[...]
def save(self, *args, **kwargs):
[custom save]
super(MyObject, self).save(args, kwargs)