很多时候,需要去其他数据库查询数据,都将会面临多数据库支持问题.

1.在settings文件内添加多数据库连接

  1. DATABASES = {
  2. 'default': {
  3. 'ENGINE': 'django.db.backends.sqlite3',
  4. 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
  5. },
  6. 'test': {
  7. 'ENGINE': 'django.db.backends.mysql',
  8. 'NAME': 'pro_control',
  9. 'USER': 'root',
  10. 'PASSWORD': 'root',
  11. 'HOST': '10.0.11.11',
  12. 'PORT': '',
  13. }
  14. }
如果默认数据库的概念在项目上下文中没有意义,则需要始终小心地指定要使用的数据库。Django需要一个default数据库,如果不需要使用,可以设置为空字典.
举个栗子
  1. DATABASES = {
  2. 'default': {},
  3. 'users': {
  4. 'NAME': 'user_data',
  5. 'ENGINE': 'django.db.backends.mysql',
  6. 'USER': 'mysql_user',
  7. 'PASSWORD': 'superS3cret'
  8. },
  9. 'customers': {
  10. 'NAME': 'customer_data',
  11. 'ENGINE': 'django.db.backends.mysql',
  12. 'USER': 'mysql_cust',
  13. 'PASSWORD': 'veryPriv@ate'
  14. }
  15. }

用例

如果你试图连接一个没有在DATABASES内定义的数据库django将产生django.db.utils.ConnectionDoesNotExist异常

将模型同步到数据库
  1. ./manage.py migrate # 操作将同步到default数据库
  2. ./manage.py migrate --database=test # 同步到test数据库

如果不是想所有的模型都同步到一个数据库上你可以定义一个database router,新建db_router.py文件

  1. class AuthRouter:
  2. def db_for_read(self, model, **hits):
  3. if model._meta.app_label == 'test01':
  4. return 'test'
  5. return None
  6.  
  7. def db_for_write(self, model, **hits):
  8. if model._meta.app_label == 'test01':
  9. return 'test'
  10. return None
  11.  
  12. def allow_relation(self, obj1, obj2, **hits):
  13. if obj1._meta.app_label == 'test01' or obj2._meta.app_label == 'test01':
  14. return True
  15. return None
  16.  
  17. def allow_migrate(self, db, app_label, model_name=None, **hits):
  18. if app_label == 'test01':
  19. return db == 'test'
  20. return None

在setting文件内添加DATABASE_ROUTERS参数

  1. DATABASE_ROUTERS = ['test01.db_router.AuthRouter', ]

为测试model指定,在test01的models文件内写入

  1. from django.db import models
  2. import shortuuid
  3.  
  4. # Create your models here.
  5.  
  6. def createuuid():
  7. return shortuuid.uuid()
  8.  
  9. class CourseManage(models.Model):
  10. """课程管控表"""
  11. uuid = models.CharField(
  12. 'ID',
  13. max_length=22,
  14. primary_key=True,
  15. default=createuuid,
  16. editable=False)
  17. add_time = models.DateTimeField('创建时间', auto_now_add=True)
  18.  
  19. del_state_type = ((0, '已删除'), (1, '默认'))
  20. modified_time = models.DateTimeField('修改时间', auto_now=True)
  21. del_state = models.IntegerField(
  22. '删除状态', choices=del_state_type, default=1, db_index=True)
  23. config_status = ((1, '进行中'), (2, '完结'), )
  24. remote_id = models.CharField(verbose_name='远端产品id', max_length=30)
  25. status = models.PositiveSmallIntegerField(choices=config_status, default=1)
  26.  
  27. class Meta:
  28. verbose_name = '课程'
  29. verbose_name_plural = verbose_name
  30. db_table = 'backend_coursemanage'

db_table指定此模型在远端的数据库内的表名称.不然会报错

按照上述操作,便能连接并查询.

标签:当项目需要执行python manage.py makemigrations时,会发现,test01项目的migrations文件夹会产生migrations文件.并且终端也会产生提示,

可以尝试删除此migrations,来避免这个问题,allow_migrate的判断只针对真正的migrate操作.

如何选择数据库?

1.模型层
  1. User.objects.using('legacy_users').get(username='fred')
  2. user_obj.save(using='new_users')
  3. user_obj.delete(using='legacy_users')

2.原生光标

  1. from django.db import connections
  2. with connections['my_db_alias'].cursor() as cursor:
  3. ...
关于replication
  1. DATABASES = {
  2. 'default': {},
  3. 'auth_db': {
  4. 'NAME': 'auth_db',
  5. 'ENGINE': 'django.db.backends.mysql',
  6. 'USER': 'mysql_user',
  7. 'PASSWORD': 'swordfish',
  8. },
  9. 'primary': {
  10. 'NAME': 'primary',
  11. 'ENGINE': 'django.db.backends.mysql',
  12. 'USER': 'mysql_user',
  13. 'PASSWORD': 'spam',
  14. },
  15. 'replica1': {
  16. 'NAME': 'replica1',
  17. 'ENGINE': 'django.db.backends.mysql',
  18. 'USER': 'mysql_user',
  19. 'PASSWORD': 'eggs',
  20. },
  21. 'replica2': {
  22. 'NAME': 'replica2',
  23. 'ENGINE': 'django.db.backends.mysql',
  24. 'USER': 'mysql_user',
  25. 'PASSWORD': 'bacon',
  26. },
  27. }
  1. import random
  2.  
  3. class PrimaryReplicaRouter:
  4. def db_for_read(self, model, **hints):
  5. """
  6. Reads go to a randomly-chosen replica.
  7. """
  8. return random.choice(['replica1', 'replica2']) # 这里是重点
  9.  
  10. def db_for_write(self, model, **hints):
  11. """
  12. Writes always go to primary.
  13. """
  14. return 'primary'
  15.  
  16. def allow_relation(self, obj1, obj2, **hints):
  17. """
  18. Relations between objects are allowed if both objects are
  19. in the primary/replica pool.
  20. """
  21. db_list = ('primary', 'replica1', 'replica2')
  22. if obj1._state.db in db_list and obj2._state.db in db_list:
  23. return True
  24. return None
  25.  
  26. def allow_migrate(self, db, app_label, model_name=None, **hints):
  27. """
  28. All non-auth models end up in this pool.
  29. """
  30. return True
 
 
 
 
 

Django 多数据库支持的更多相关文章

  1. Django之 数据库ORM

    一.ORM Django的 业务 少不了 跟数据库打交道,不然没有数据库保存一些数据将是一件很糟糕的事情.Django 对 数据库 支持原生的 SQL语句,但更好的对数据库支持,Django自己有一套 ...

  2. [django]Django站点admin支持中文显示和输入设置

    正文: Django站点admin支持中文输入设置,操作如下: 1 需要确定的你的数据库的client客户端和服务端的编码设置为utf-8,如果不是,请将其设置成utf-8编码,我采用mysql,详情 ...

  3. django 操作数据库--orm(object relation mapping)---models

    思想 django为使用一种新的方式,即:关系对象映射(Object Relational Mapping,简称ORM). PHP:activerecord Java:Hibernate C#:Ent ...

  4. python学习笔记--Django入门三 Django 与数据库的交互:数据建模

    把数据存取逻辑.业务逻辑和表现逻辑组合在一起的概念有时被称为软件架构的 Model-View-Controller (MVC)模式.在这个模式中, Model 代表数据存取层,View 代表的是系统中 ...

  5. Django模型-数据库操作

    前言 前边记录的URLconf和Django模板全都是介绍页面展示的东西,也就是表现层的内容.由于Python先天具备简单而强大的数据库查询执行方法,Django 非常适合开发数据库驱动网站. 这篇开 ...

  6. Django: 之数据库导入、迁移和联用

    Django 数据库导入 从网上下载的一些数据,excel表格,xml文件,txt文件等有时候我们想把它导入数据库,应该如何操作呢? 以下操作符合 Django版本为 1.6 ,兼顾 Django 1 ...

  7. django模型——数据库(二)

    模型--数据库(二) 实验简介 模型的一些基本操作,save方法用于把对象写入到数据库,objects是模型的管理器,可以使用它的delete.filter.all.order_by和update等函 ...

  8. Django 2.0 学习(16):Django ORM 数据库操作(下)

    Django ORM数据库操作(下) 一.增加表记录 对于表单有两种方式: # 方式一:实例化对象就是一条表记录france_obj = models.Student(name="海地&qu ...

  9. django models 数据库操作

    django models 数据库操作 创建模型 实例代码如下 from django.db import models class School(models.Model): pass class ...

随机推荐

  1. java中 & ^ ~ 的运算

    java运算符 与(&).非(~).或(|).异或(^)   最近看HashMap源码,遇到了这样一段代码: 1 static final int hash(Object key) { 2 i ...

  2. eclipse下将maven项目打包为jar(1.不带第三方jar,2.带第三方jar)

    由于项目需要讲maven项目打包为jar包,由于之前没类似经验,百度找例子走了不少弯路,这边随手记录下,网上说的 开发工具:eclipse jar包管理:maven 一般打包出来的jar包分为两种 一 ...

  3. 探寻 JavaScript 精度问题

    阅读完本文可以了解到 0.1 + 0.2 为什么等于 0.30000000000000004 以及 JavaScript 中最大安全数是如何来的. 十进制小数转为二进制小数方法 拿 173.8125 ...

  4. You earned your Program Management Professional (PgMP)® Credential

    You earned your Program Management Professional (PgMP)® Credential. pasting

  5. HTML之超链接

    图像标签 图像标签为 <img> ,它是行内元素,其主要功能是在网页里面插入图像,所插入图片由属性 scr 属性决定.主要格式为 <img scr="URL"&g ...

  6. 输入输出流ObjectInputStream、ObjectOutputStream(对象序列化与反序列化)

    对象的输入输出流 : 主要的作用是用于写入对象信息与读取对象信息. 对象信息一旦写到文件上那么对象的信息就可以做到持久化了 对象的输出流: ObjectOutputStream 对象的输入流:  Ob ...

  7. es6 模本字符串拼接方法 ``

    1.字符串拼接  可以使用 es6  ` ` 配合 ${xxx} 具体操作上代码 <!DOCTYPE html> <html lang="en"> < ...

  8. JQuery的Ajax技术

    jquery是一个优秀的js框架,自然对js原生的ajax进行了封装, 封装后的ajax的操作方法更简洁,功能更强大,与ajax操作 相关的jquery方法有如下几种: Ajax 请求 $.ajax( ...

  9. rt-thread 之网络组件

    @2019-02-23 [小记] 文件 <net_sockets.c> 为兼容标准 BSD Socket API 文件 <sal_socket.c> 为网络中间抽象层 文件 & ...

  10. Loj 10115 「一本通 4.1 例 3」校门外的树 (树状数组)

    题目链接:https://loj.ac/problem/10115 题目描述 原题来自:Vijos P1448 校门外有很多树,学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的 ...