django多数据库

阅读spider platform时发现前端项目中使用了多数据库,那么django实现多数据库需要哪些配置呢,又如何使用呢?

定义及路由机制

定义

在settings里面的DATABASES是一个字典,用于定义需要的数据库,如下,一共定义了两个数据库。

DATABASES = {

'default': {

'NAME': 'app_data',

'ENGINE': 'django.db.backends.postgresql_psycopg2',

'USER': 'postgres_user',

'PASSWORD': 's3krit'

},

'user1': {

'NAME': 'user1_data',

'ENGINE': 'django.db.backends.mysql',

'USER': 'mysql_user',

'PASSWORD': 'priv4te'

}

'user2': {

'NAME': 'user2_data',

'ENGINE': 'django.db.backends.mysql',

'USER': 'mysql_user',

'PASSWORD': 'priv4te'

}

}

那么什么时候调用default什么时候调用users数据库呢,这就需要下面的路由。

路由注册

class User1Router(object):

""" A router to control all database operations on models in the auth application. """

def db_for_read(self, model, **hints):

""" Attempts to read auth models go to auth_db. """

if model._meta.app_label == 'auth':

return 'user1'

return None

def db_for_write(self, model, **hints):

""" Attempts to write auth models go to auth_db. """

if model._meta.app_label == 'auth':

return 'user1'

return None

def allow_relation(self, obj1, obj2, **hints):

""" Allow relations if a model in the auth app is involved. """

if obj1._meta.app_label == 'auth' or \

obj2._meta.app_label == 'auth':

return True

return None

def allow_syncdb(self, db, model):

""" Make sure the auth app only appears in the 'auth_db' database. """

if db == 'auth_db':

return model._meta.app_label == 'auth'

elif model._meta.app_label == 'user1':

return False

return None

class User2Router(object):

""" A router to control all database operations on models in the auth application. """

def db_for_read(self, model, **hints):

""" Attempts to read auth models go to auth_db. """

if model._meta.app_label == 'auth2':

return 'user2'

return None

def db_for_write(self, model, **hints):

""" Attempts to write auth models go to auth_db. """

if model._meta.app_label == 'auth2':

return 'user2'

return None

def allow_relation(self, obj1, obj2, **hints):

""" Allow relations if a model in the auth app is involved. """

if obj1._meta.app_label == 'auth' or \

obj2._meta.app_label == 'auth':

return True

return None

def allow_syncdb(self, db, model):

""" Make sure the auth app only appears in the 'auth_db' database. """

if db == 'auth_db':

return model._meta.app_label == 'auth2'

elif model._meta.app_label == 'user2':

return False

return None

User1Router的路由逻辑是,如果model所属的app是auth的话,就使用user1数据库,否则就使用其他的;User2Router的逻辑类似。

如何注册路由

光定义路由程序无法调用到,还需要注册到django中,在settings中定义

DATABASE_ROUTERS = ['path.to.User1Router' , 'path.to.User2Router']

path.to:是User1Router的完整python包路径,所以,User1Router不一定要在settings中实现,可以在任何地方。

路由机制

那么django是如何选择其中一个路由的呢?

1. django按照注册的顺序轮询DATABASE_ROUTERS,所以首先验证User1Router是否返回了非空字符串,如果是,则使用User1Router;如果不是则接着验证后面的Router;

2. 同样验证User2Router,如果User2Router返回了非空字符串,则使用User2Router;如果不是则使用default数据库;

3. 所以可以看出,路由注册的顺序是会影响最后的结果的,注册在前面的路由会优先被使用;

自动路由和手动路由

上面定义的Router是自动路由,意思是django会自动轮询所注册的路由器,某个model会保存在哪个数据库,是django通过注册的Router自动获得的,在编码中你不需要指定;

手动路由,则是你可以在编码中指定某个model要保存到哪个数据库。

而且手动路由也有性能方面的优点,如果定义了很多个数据库,每次保存或者读取model都要把轮询一遍路由列表,显然效率有些低,如果程序逻辑清楚的知道当前的代码应该连接哪个数据库,显示指定的方式显然效率更高。

手动路由

查询

使用using函数,参数就是要查询的数据库

User.objects.using('user1').all()

保存或者更新

使用save的using参数,值就是要使用的数据库

>>> my_object.save(using='user1')

删除

使用delete的using参数

>>> user_obj.delete(using='user1')

分库技术

下面紧紧介绍分库的思路。

垂直分库

即一个app对应一个数据库,上面自动路由的例子就是一个垂直分库的例子,auth1使用user1数据库,auth2使用user2数据库。当然也可以使用手动路由。

水平分库

水平分库建议使用手动路由,因为每个model的分库机制可能都不一样,自动路由实现起来有些麻烦会造成性能不高,而手动路由,每个model根据自己的规则来获得不同的数据库。

django 配置 多数据库的更多相关文章

  1. DJango配置mysql数据库以及数据库迁移

    DJango配置mysql数据库以及数据库迁移 一.Django 配置MySQL数据库 在settings.py中配置 import pymysql # 配置MySQL pymysql.install ...

  2. Django配置Mysql数据库 (Pycharm)

    Django配置MySQL数据库方法 一.settings.py文件中修改数据库配置为下面的内容: # Database # https://docs.djangoproject.com/en/2.0 ...

  3. Django 配置MySQL数据库 mysql

    Django 配置MySQL数据库 在settings.py中配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # ...

  4. Django配置MariaDB数据库

    Django中配置MariaDB数据库.配置文件如下: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': ...

  5. 【python-Django开发】Django 配置MySQL数据库讲解!!!

    官方文档请阅读:https://docs.djangoproject.com/en/1.11/ref/databases/#mysql-db-api-drivers 配置MySQL数据库 1. 新建M ...

  6. Django配置实现数据库读写分离

    django在进行数据库操作的时候,读取数据与写数据(增.删.改)可以分别从不同的数据库进行操作. 1. 在配置文件中增加slave数据库的配置 2. 创建数据库操作的路由分发类 在meiduo_ma ...

  7. django配置-mysql数据库相关配置

    Django3版本之前的配置 1. Django默认配置的数据库是sqlite 2. 使用mysql数据库需要下载的包 pip3 install PyMySQL 3. Django配置PyMySQL ...

  8. Django 配置MySQL数据库

    在settings.py中配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 数据库引擎 'NAME': 'my ...

  9. Django配置MySQL数据库

    一.在settings.py中配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 数据库引擎 'NAME': ' ...

随机推荐

  1. C#新特性, dynamic, ExpandObject

    http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject.aspx using System; using System ...

  2. C++语言基础(22)-转换构造函数和类型转换函数

    一.转换构造函数 将其它类型转换为当前类类型需要借助转换构造函数(Conversion constructor).转换构造函数也是一种构造函数,它遵循构造函数的一般规则.转换构造函数只有一个参数. # ...

  3. 解决eclipse偶尔无视breakpoint的行为

    一般是如果你使用了T[]这样的参数列表,也就是generic array作为参数,你就算给函数打了断点,有时也会被eclipse无视 比如如下代码,你在调试main的时候,eclipse就会把doPa ...

  4. Cannot change version of project facet Dynamic Web Module to 3.0 requires Java 1.6 or newer 解决方案

    Eclipse Maven 开发一个 jee 项目时,编译时遇到以下错误:Description Resource Path Location TypeDynamic Web Module 3.0 r ...

  5. 【转】redis C接口hiredis 简单函数使用介绍

    from : http://blog.csdn.net/kingqizhou/article/details/8104693 hiredis是redis数据库的C接口,目前只能在linux下使用,几个 ...

  6. tomcat修改默认端口

    1.webserver: tomcat2.version:   Apache Tomcat/7.0.293.operation: 修改默认端口 3.1 修改tomcat目录下的/conf/server ...

  7. find命令结合cp bash mv 命令使用的4种方式

    工作经常需要用find结合其它命令一起使用,下面介绍4种结合方式. 例: 用find查找/data目录下,以.txt文件结尾的文件并复制到/tmp下 方法一 find与|xargs是黄金搭档,-t 参 ...

  8. EEPlat的基于浏览器的在线开发技术

    EEPlat的开发内容主要包含配置开发和基于API的扩展开发两块内容. EEPlat的配置开发基于后台的配置环境.直接通过界面操作配置就可以. EEPlat的配置平台是用EEPlat自解释构建的.本身 ...

  9. php在linux中执行外部命令

    目录:一.PHP中调用外部命令介绍二.关于安全问题三.关于超时问题四.关于PHP运行linux环境中命令出现的问题 一.PHP中调用外部命令介绍在PHP中调用外部命令,可以用,1>调用专门函数. ...

  10. iOS conformsToProtocol

    - (BOOL)conformsToProtocol:(Protocol *)aProtocol; 是用来检查对象(包括其祖先)是否实现了指定协议类的方法. 今天遇到一个问题,一个类没有实现proto ...