2010-10-28 83 views
4

使用Django multidb,编写运行主/从基础架构的router相当容易。但是有可能写一个写入到多个数据库的路由器吗?我的用例是一组项目,全部运行在同一个域中。为了避免用户在每个站点注册/登录,我想同步contrib.authcontrib.sessions表。这可能与Django的multidb或我应该看看数据库系统的复制功能(在我的情况下MySQL)?Django multidb:写入多个数据库

回答

4

我正在研究Django分片架构。

我看着Django路由器,但决定推出自己的。

对您的问题的一些想法:

  1. 一个想法是使用一个数据库,然后通过使用上Django的信号在合适的数据复制后保存。通过内部的Django的各种神奇发生的引擎盖下

东西like--

import settings.databases as dbs_list 

def post_save_function(UserModel): 
    for db in dbs_list: 
      UserModel.save(using=db,force_insert=True) 

节省用户对象(至少在单DB型)似乎保存会话,身份验证等数据.contrib,所以你有可能不必进入并找出所有这些数据库表的名称和类型。为了支持这种工作的可能性,我发誓我最近在某处(可能在Alex Gaynor的博客文章中)读到,如果一个对象有一个外键,Django将尝试使用该对象所在的同一个DB(鉴于Django通常运作的方式,这是显而易见的原因)。

  1. 另一个想法:

从Django的multiDB页面上的例子中,你提到我不知道像下面将工作:

他们的示例代码:

def allow_syncdb(self, db, model): 
     "Explicitly put all models on all databases." 
     return True 

可能的修改:

高清allow_syncdb(个体经营,DB型):

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

+0

嗨,感谢您的评论。由于我们在LDAP/Kerberos系统上提供集中身份验证和单点登录,因此我不再追究这个特定问题。 – 2011-03-29 22:27:44

5

我想你会得到更好的实现了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): 
     .... 

希望这将有助于:)

+0

我将不得不改变Django的源代码,这个工作(正如我在质询时说,我要复制的表是从'contrib.auth'和'contrib.sessions')。如果可能的话,我想避免与Django本身混淆。 – 2010-10-28 10:12:18

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)