django 多数据库配置教程


Posted in Python onMay 30, 2018

在django项目中, 一个工程中存在多个APP应用很常见. 有时候希望不同的APP连接不同的数据库,这个时候需要建立多个数据库连接。

1. 修改项目的 settings 配置

在 settings.py 中配置需要连接的多个数据库连接串

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': os.path.join(BASE_DIR, 'sqlite3'),
  },
  'db01': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': os.path.join(BASE_DIR, 'db_01'),
  },
  'db02': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': os.path.join(BASE_DIR, 'db_02'),
  },
}

假设现在我们用到3个数据库,一个default默认库,一个 db01 和 db02

2. 设置数据库的路由规则方法

在 settings.py 中配置 DATABASE_ROUTERS

DATABASE_ROUTERS = ['Prject.database_router.DatabaseAppsRouter']

Project: 建立的django项目名称(project_name)

database_router: 定义路由规则database_router.py 文件名称, 这个文件名可以自己定义

DatabaseAppsRouter: 路由规则的类名称,这个类是在database_router.py 文件中定义

3. 设置APP对应的数据库路由表

每个APP要连接哪个数据库,需要在做匹配设置,在 settings.py 文件中做如下配置:

DATABASE_APPS_MAPPING = {
  # example:
  # 'app_name':'database_name',
  'app02': 'db02',
  'app01': 'db01',
  'admin': 'db01',
  'auth': 'db01',
  'contenttypes': 'db01',
  'sessions': 'db01',
}

以上的app01, app02是项目中的 APP名,分别指定到 db01, db02 的数据库。

为了使django自己的表也创建到你自己定义的数据库中,你可以指定 : admin, auth, contenttypes, sessions 到设定的数据库中,如果不指定则会自动创建到默认(default)的数据库中

4. 创建数据库路由规则

在项目工程根路径下(与 settings.py 文件一级)创建 database_router.py 文件:

from django.conf import settings
DATABASE_MAPPING = settings.DATABASE_APPS_MAPPING
class DatabaseAppsRouter(object):
  """
  A router to control all database operations on models for different
  databases.
  In case an app is not set in settings.DATABASE_APPS_MAPPING, the router
  will fallback to the `default` database.
  Settings example:
  DATABASE_APPS_MAPPING = {'app1': 'db1', 'app2': 'db2'}
  """
  def db_for_read(self, model, **hints):
    """"Point all read operations to the specific database."""
    if model._meta.app_label in DATABASE_MAPPING:
      return DATABASE_MAPPING[model._meta.app_label]
    return None
  def db_for_write(self, model, **hints):
    """Point all write operations to the specific database."""
    if model._meta.app_label in DATABASE_MAPPING:
      return DATABASE_MAPPING[model._meta.app_label]
    return None
  def allow_relation(self, obj1, obj2, **hints):
    """Allow any relation between apps that use the same database."""
    db_obj1 = DATABASE_MAPPING.get(obj1._meta.app_label)
    db_obj2 = DATABASE_MAPPING.get(obj2._meta.app_label)
    if db_obj1 and db_obj2:
      if db_obj1 == db_obj2:
        return True
      else:
        return False
    return None
  def allow_syncdb(self, db, model):
    """Make sure that apps only appear in the related database."""
    if db in DATABASE_MAPPING.values():
      return DATABASE_MAPPING.get(model._meta.app_label) == db
    elif model._meta.app_label in DATABASE_MAPPING:
      return False
    return None
  def allow_migrate(self, db, app_label, model=None, **hints):
    """
    Make sure the auth app only appears in the 'auth_db'
    database.
    """
    if db in DATABASE_MAPPING.values():
      return DATABASE_MAPPING.get(app_label) == db
    elif app_label in DATABASE_MAPPING:
      return False
    return None

5. Models创建样例

在各自的 APP 中创建数据表的models时,必须要指定表的 app_label 名字,如果不指定则会创建到 default 中配置的数据库名下,

如下:

在app01下创建models

class Users(models.Model):
  name = models.CharField(max_length=50)
  passwd = models.CharField(max_length=100)
  def __str__(self):
    return "app01 %s " % self.name
  class Meta:
    app_label = "app01"

在app02下创建models

class Users(models.Model):
  username = models.CharField(max_length=100)
  password = models.CharField(max_length=50)
  age = models.IntegerField()
  def __str__(self):
    return "app02 %s" % self.username
  class Meta:
    app_label = "app02"
class Book(models.Model):
  user = models.ForeignKey("Users", on_delete=models.CASCADE)
  bookname = models.CharField(max_length=100)
  def __str__(self):
    return "%s: %s" % (self.user.username, self.bookname)
  class Meta:
    app_label = "app02"

在 app03创建models 未指定 app_label,创建到default下

class Users(models.Model):  
  username = models.CharField(max_length=100)

6. 生成数据表

在使用django的 migrate 创建生成表的时候,需要加上 ?database 参数,如果不加则将 未 指定 app_label 的 APP的models中的表创建到default指定的数据库中,如:

将app01下models中的表创建到db01的数据库”db_01”中

./ manage.py migrate --database=db01

将app02下models中的表创建到db02的数据库”db_02”中

./ manage.py migrate --database=db02

将app03下models中的表创建到default的数据库”sqlite3”中

./ manage.py migrate

以上创建完成后,其它所有的创建、查询、删除等操作就和普通一样操作就可以了,无需再使用类似

models.User.objects.using(dbname).all()

这样的方式来操作。

以上这篇django 多数据库配置教程就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
朴素贝叶斯算法的python实现方法
Nov 18 Python
Python函数式编程指南(一):函数式编程概述
Jun 24 Python
Python批量查询域名是否被注册过
Jun 21 Python
python如何使用正则表达式的前向、后向搜索及前向搜索否定模式详解
Nov 08 Python
Python中.join()和os.path.join()两个函数的用法详解
Jun 11 Python
pandas筛选某列出现编码错误的解决方法
Nov 07 Python
Pandas过滤dataframe中包含特定字符串的数据方法
Nov 07 Python
Python Request爬取seo.chinaz.com百度权重网站的查询结果过程解析
Aug 13 Python
python3中rank函数的用法
Nov 27 Python
Django单元测试中Fixtures的使用方法
Feb 26 Python
基于Python共轭梯度法与最速下降法之间的对比
Apr 02 Python
如何理解python对象
Jun 21 Python
python实现超市扫码仪计费
May 30 #Python
pycharm 将django中多个app放到同个文件夹apps的处理方法
May 30 #Python
多个应用共存的Django配置方法
May 30 #Python
python实现支付宝当面付(扫码支付)功能
May 30 #Python
详解Python3.6安装psutil模块和功能简介
May 30 #Python
python3之模块psutil系统性能信息使用
May 30 #Python
python批量导入数据进Elasticsearch的实例
May 30 #Python
You might like
十天学会php之第七天
2006/10/09 PHP
PHP迅雷、快车、旋风下载专用链转换代码
2010/06/15 PHP
PHP实现多进程并行操作的详解(可做守护进程)
2013/06/18 PHP
win7下memCache的安装过程(具体操作步骤)
2013/06/28 PHP
PHP包含文件函数include、include_once、require、require_once区别总结
2014/04/05 PHP
适用于初学者的简易PHP文件上传类
2015/10/29 PHP
Laravel+jQuery实现AJAX分页效果
2016/09/14 PHP
php文件类型MIME对照表(比较全)
2016/10/07 PHP
Javascript模块化编程(三)require.js的用法及功能介绍
2013/01/17 Javascript
ExtJS自定义主题(theme)样式详解
2013/11/18 Javascript
浅谈javascript 函数属性和方法
2015/01/21 Javascript
基于JavaScript实现跳转提示页面
2016/09/24 Javascript
JavaScript实现经典排序算法之选择排序
2016/12/28 Javascript
React Router基础使用
2017/01/17 Javascript
利用javascript实现的三种图片放大镜效果实例(附源码)
2017/01/23 Javascript
JS简单封装的图片无缝滚动效果示例【测试可用】
2017/03/22 Javascript
bootstrap+jQuery 实现下拉菜单中复选框全选和全不选效果
2017/06/12 jQuery
Vue.js结合bootstrap前端实现分页和排序效果
2018/12/29 Javascript
vue中子组件传递数据给父组件的讲解
2019/01/27 Javascript
python计算最小优先级队列代码分享
2013/12/18 Python
python同时给两个收件人发送邮件的方法
2015/04/30 Python
Python中字典的基础知识归纳小结
2015/08/19 Python
Python实现的异步代理爬虫及代理池
2017/03/17 Python
Python装饰器(decorator)定义与用法详解
2018/02/09 Python
用python与文件进行交互的方法
2018/03/01 Python
浅谈在django中使用filter()(即对QuerySet操作)时踩的坑
2020/03/31 Python
浅谈keras2 predict和fit_generator的坑
2020/06/17 Python
Python实现自动签到脚本的示例代码
2020/08/19 Python
Django修改app名称和数据表迁移方案实现
2020/09/17 Python
比较一下entity bean和session bean
2013/12/27 面试题
自动化专业本科毕业生求职信
2013/10/20 职场文书
大专应届生个人的自我评价
2013/11/21 职场文书
期中考试后的反思
2014/02/08 职场文书
房地产端午节活动方案
2014/08/24 职场文书
股权转让协议书
2014/12/07 职场文书
永远是春天观后感
2015/06/12 职场文书