django多数据库router源码

本文介绍了Django中实现多数据库路由的具体方法。通过自定义路由器类MyDBrouter,可以针对不同应用的数据读写操作指定不同的数据库。文章详细展示了如何配置settings.py文件,并解释了Django内部是如何利用这些配置来实现数据库请求的智能分发。

首先router的使用:

django的多数据库,需要经过 router 进行分流。

router的配置如下,首先是 router 类:db_routers.py

class MyDBrouter():
    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'goods':
            return 'goods'
        else:
            return 'default'

    def db_for_write(self, model, **hints):
        if model._meta.app_label == 'goods':
            return 'goods'
        else:
            return 'default'

然后将其加入配置:setting.py

DATABASE_ROUTERS = ('common.db_routers.MyDBrouter',)

其次是router的源码

django.db.utils.py

class ConnectionRouter:
    def __init__(self, routers=None):
        """
        If routers is not specified, default to settings.DATABASE_ROUTERS.
        """
        self._routers = routers
	
	# 经过这个方法,将setting的配置引入到 routers 
    @cached_property
    def routers(self):
        if self._routers is None:
            self._routers = settings.DATABASE_ROUTERS
        routers = []
        for r in self._routers:
            if isinstance(r, str):
                router = import_string(r)()
            else:
                router = r
            routers.append(router)
        return routers

	# 真正的执行分流的方法
    def _router_func(action):
        def _route_db(self, model, **hints):
            chosen_db = None
            for router in self.routers:
                try:
                    method = getattr(router, action)  
                except AttributeError:
                    # If the router doesn't have a method, skip to the next one.
                    pass
                else:
                    chosen_db = method(model, **hints)
                    if chosen_db:
                        return chosen_db
            instance = hints.get('instance')
            if instance is not None and instance._state.db:
                return instance._state.db
            return DEFAULT_DB_ALIAS
        return _route_db

    db_for_read = _router_func('db_for_read')
    db_for_write = _router_func('db_for_write')

核心方法是这两句

method = getattr(router, action)   # 引入了分流类的方法
chosen_db = method(model, **hints)  # 执行分流类的方法,比如,此处返回值可能是 "goods"

然后,这个chosen_db 会被 django.db.models.query.py 中的 属性方法 db 调用

    @property
    def db(self):
        """Return the database used if this query is executed now."""
        if self._for_write:
            return self._db or router.db_for_write(self.model, **self._hints)
        return self._db or router.db_for_read(self.model, **self._hints)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值