zoukankan      html  css  js  c++  java
  • 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所属的app
    11             return 'huodongapp'
    12         return None
    13 
    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 'huodongapp'
    20         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 router
    class 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

  • 相关阅读:
    IIS+PHP+MYSQL搭建
    visual studio 2013 打开失败 ,报错:未能完成操作,不支持此接口
    sql错误;The user specified as a definer ('tester'@'%') does not exist
    mysql报错:You must reset your password using ALTER USER statement before executing this statement.
    win 7下安装mysql zip格式
    微信小程序注册使用流程
    软件风险
    成熟度等级CMM
    软件工程活动
    tomcat
  • 原文地址:https://www.cnblogs.com/livingintruth/p/3794325.html
Copyright © 2011-2022 走看看