首页 > 代码库 > django multidb --- router

django multidb --- router

之前一篇随笔, 提到了django中怎么使用多数据库, 但是在实际工程中遇到了一个问题,就是admin指定了使用某库, 在测试环境上没问题, 当部署后(库也变动了位置), 修改一个admin的model object保存后就报错.

  No such table

追溯了下源码, 没有找到问题,  但可以确定的是那个保存操作并没有使用到我们指定的数据库,使用了default.

最后是使用了django的router解决了这个问题

 

那么django的router是什么?

就是一个类, 定义了如下方法

db_for_read(model, **hints)db_for_write(model, **hints)allow_relation(obj1, obj2, **hints)allow_syncdb(db, model)

 

django router有什么用?

看这个函数名我们就知道了, 我们可以决定一个model在读的时候用哪个db,  db_for_read返回一个settings.DATABASES中的db名或者None

 

比如在写这篇笔记实际经历的项目中, 我们要让一个叫做huodongappcms的app的所有model都读写一个远程数据库(配置为huodongapp), 我们在这个app的models中定义了么一个router

 1 class HuodongappcmsRouter(object): 2     """ 3     A router to control all database operations on models in the 4     this app. 5     """ 6     def db_for_read(self, model, **hints): 7        """ 8         Attempts to read auth models go to auth_db. 9        """10         if model._meta.app_label == huodongappcms:     #model所属的app11             return huodongapp12         return None13 14     def db_for_write(self, model, **hints):15         """16         Attempts to write auth models go to auth_db.17         """18         if model._meta.app_label == huodongappcms:19             return huodongapp20         return None

 

然后加入settings中的DATABASE_ROUTERS, 使用Router的全路径, django会根据DATABASE_ROUTERS中router指定的顺序依次调用.

DATABASE_ROUTERS = [huodongappcms.models.HuodongappRouter]

 当我添加了如上的Router后 ,我去掉了huodongapp中admin对多数据库的想关定制, 一样是work的

 

 

2. 如果我们还想让这个app以外的其它app写都写到一个主库master中, 读都随机的从两个从库slave1, slave2之一读, 那么写这样一个Router

class MasterSlaveRouter(object):    def db_for_read(self, model, **hint):        import random        return random.choice([slave1, slave2])    def db_for_write(self, model, **hint):        return master

 

然后加入到DATABASE_ROUTERS中

 

 

3, 稍微追溯一下源码, 当需要一个db时, 拿数据库的manager举例, 会通过django.db的router去获取

而router就是django.db.utils中定义的一个类, 它使用了DATABASE_ROUTERS配置. 

下面是Manager的db方法.

from django.db import routerclass Manager():    @property    def db(self):                  return self._db or router.db_for_read(self.model)

 

 

这里只讨论了django Router的db_for_read和db_for_write

和ForeignKey相关西的allow_relation以及用于数据库同步的allow_sync以后讨论

 

 

参考:

https://docs.djangoproject.com/en/1.6/topics/db/multi-db/#automatic-database-routing