• 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

  • 相关阅读:
    386. Lexicographical Numbers 输出1到n之间按lexico排列的数字序列
    287. Find the Duplicate Number 找出数组中的重复数字
    165. Compare Version Numbers比较版本号的大小
    java之spring mvc之文件上传
    java之spring mvc之Restful风格开发及相关的配置
    java之spring mvc之页面跳转
    java之spring mvc之数据处理
    java之spring mvc之Controller配置的几种方式
    java之spring mvc之helloworld
    java之spring mvc之初始spring mvc
  • 原文地址:https://www.cnblogs.com/livingintruth/p/3794325.html
Copyright © 2020-2023  润新知