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

被折叠的 条评论
为什么被折叠?



