python3之Django多数据库
1、定义数据库
在django项目中, 一个工程中存在多个APP应用很常见;有时候希望不同的APP连接不同的数据库,这个时候需要建立多个数据库连接。
在Django的setting中使用DATABASES设置定义数据库,可以将数据库映射到特定的别名字典中;DATABASES定义的是要给嵌套字典,该设置必须配置default默认数据库。默认使用SQLite进行单一数据库设置:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'mydatabase',
}
}
如不使用默认数据库定义可以将默认配置为空字典形式:
'default':{}
(1) DATABASES内部选项:
ATOMIC_REQUESTS:为True时数据库事务包装每个视图,默认为False
AUTOCOMMIT:为False时禁用Django事务管理,默认为True
ENGINE:设置数据库类型
'django.db.backends.postgresql'
'django.db.backends.mysql'
'django.db.backends.sqlite3'
'django.db.backends.oracle'
HOST:指定连接的主机名或ip地址,如果使用(‘/’)正斜杠开头则通过套接字连接:
'HOST':'127.0.0.1' #TCP套接字连接
'HOST':'/var/run/mysql' #UNIX套接字
NAME:制定使用的数据库名,对于SQLite它是指定数据库文件的路径,在window上也要使用正斜杠。
'NAME':'databasename'
'NAME':'C:/user/mysite/sqlite3.db'
CONN_MAX_AGE:数据库连接的生命周期,默认为0请求结束时关闭数据库,设置为None无限持久连接。
OPTIONS:链接到数据库时使用的额外参数,可用参数因数据库类型而异。
'OPTIONS':{'read_default_file':'path/to/my.cnf',} #优先于NAME,USER,PASSWORD,HOST,PORT
#设置mysql启用严格模式
'OPTIONS':{'init_command':"SET sql_mode='STRICT_TRANS_TABLES'"}
PASSWORD:设置密码,不与SQLite一起使用
PORT:指定端口
TIME_ZONE:设置时区
DISABLE_SERVER_SIDE_CURSORS:True时禁用服务器端游标
USER:链接用户名
TEST:测试数据库
(2)自定义数据库
#自定义两个mysql数据库映射到db1和db2上
'db1':{
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db1',
'USER': 'root',
'PASSWORD': '123.com',
'HOST': '172.16.32.133',
'PORT': '',
'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
}, #mysql使用严格模式,不指定会有警告信息
},
'db2':{
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db2',
'USER': 'root',
'PASSWORD': '123.com',
'HOST': '172.16.32.133',
'PORT': '',
'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
}
如果访问没有在DATABASES中定义的数据库,Django会报:django.db.utils.ConnectionDoesNotExist 异常。
2、同步数据库
migrate管理命令会同时在每一个数据库上运行,默认情况下它在default数据库上运行 ,可以通过选项 --database来指定需要同步的数据库。如不指定会同步到default数据库上。
迁移同步命令:
makemigrations:根据简称到的变化创建新的迁移。
migrate:将模型和迁移数据同步到数据库中。
通过上面的列子,将每个应用程序同步到特定的数据库:
#python manage.py migrate #同步默认数据库
#python manage.py migrate --database=db1
#python manage.py migrate --database=db2
多个数据库导出:
python manage.py dumpdata app01 --database=db1 > app1_fixture.json
python manage.py dumpdata app02 --database=db2 > app2_fixture.json
python manage.py dumpdata auth > auth_fixture.json
多个数据库导入:
python manage.py loaddata app1_fixture.json --database=db1
python manage.py loaddata app2_fixture.json --database=db2
3、自动数据库路由
使用多个数据库时最简单的方法是设置数据库路由方案,以保证对象对原始数据库的“粘性",默认所有的查询都会返回到default数据库中。
数据库路由器是一个最多提供四种方法的类:
db_for_read(model,**hints) :应用于读取类型对象的数据库模型,如果数据库提供附加信息会在hints字典中提供,最后如果没有则返回None
db_for_write(model,**hints):应用于写入类型对象的数据库模型,hints字典提供附加信息,如果没有则返回None
allow_relation(obj1,obj2,**hints):外键操作,判断两个对象之间是否是应该允许关系,是返回True,否则返回False,如果路由允许返回None
allow_migrate(db,app_label,model_name=None,**hints):db确定是否允许在具有别名的数据库上运行迁移操作,操作运行返回True,否则返回False,或者返回None,如果路由器没有意见。
app_label:位置参数是正在迁移的应用程序的标签。
model_name:多个迁移操作设置模型的值,如:model._meta.app_label
(1)定义数据库路由方法类
在项目工程根路径下(与 settings.py 文件一级)创建数据库路由表,app应用会根据指定的路由选择数据库:
app01,app02分别使用db1和db2数据库:
#!/usr/bin/env python
#coding:utf8
from django.conf import settings DATABASE_MAPPING = settings.DATABASE_APPS_MAPPING #在setting中定义的路由表 class DatabaseAppsRouter(object):
def db_for_read(self, model, **hints):
if model._meta.app_label in DATABASE_MAPPING:
return DATABASE_MAPPING[model._meta.app_label]
return None def db_for_write(self, model, **hints): if model._meta.app_label in DATABASE_MAPPING:
return DATABASE_MAPPING[model._meta.app_label]
return None def allow_relation(self, obj1, obj2, **hints): 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): 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_name=None, **hints):
if db in DATABASE_MAPPING.values():
return DATABASE_MAPPING.get(app_label) == db
elif app_label in DATABASE_MAPPING:
return False
return None
(2)使用路由数据库
在setting.py中配置DATABASE_ROUTERS指定自由路由文件:
#test_django为项目名,database_router为路由文件名,DatabaseAppsRouter为路由中创建的类名 DATABASE_ROUTERS = ['test_django.database_router.DatabaseAppsRouter']
在setting.py中DATABASE_ROUTERS下面设置app与数据库匹配路由表,采用字典方式app名对应数据库映射名:
DATABASE_APPS_MAPPING = {
'app01':'db1',
'app02':'db2',
}
(3)生成数据表并同步数据
分别在app01和app02下创建model类,用于生成数据表:
app01:
from django.db import models # Create your models here.
class ap1(models.Model):
username = models.CharField(max_length=30)
class Meta:
#app_label = 'app02' #如果指定将在app02对应的数据库下创建数据表 class ap2(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
birth_date = models.DateField()
app02:
from django.db import models class ap3(models.Model):
app2_name = models.CharField(max_length=50)
sex = models.CharField(max_length=50)
data = models.DateField() class ap4(models.Model):
app2 = models.CharField(max_length=50)
sex1 = models.CharField(max_length=50)
data1 = models.DateField()
class Meta:
db_table = 'mytable' #自定义表名称
migrate管理命令一次只能操作一个数据库,默认操作default数据库,使用--database指定同步的数据库:
#python manage.py migrate #生成表数据同步
#python manage.py makemigrations #创建变动数据
#python manage.py migrate --database=db1 #同步指定数据库
#python manage.py migrate --database=db2
需要注意:在多个app分库时,必须指定每个app对应的数据库,否则在同步数据 库时将没指定的app模板都同步到同步数据库中。
4、手动选择数据库
使用using()指定查询的数据库的别名:
>>> # So will this.
>>> Author.objects.using('default').all() >>> # This will run on the 'other' database.
>>> Author.objects.using('other').all()
保存数据,Model.save()指定将数据保存到哪个数据库中:
>>> my_object.save(using='legacy_users') #会将数据保存到legacy_users数据库中,如不指定会保持到默认数据库中。
>>> my_object.delete(using='legacy_users')
#删除指定数据库
移动对象到另一个数据库时会发生主键冲突,可以使用obj.pk方法清除主键再保存对象。
>>> p = Person(name='Fred')
>>> p.save(using='first')
>>> p.pk = None # Clear the primary key.
>>> p.save(using='second') # Write a
--------------------------------------------------------------------------
python3之Django多数据库的更多相关文章
- Linux下安装Python3的django并配置mysql作为django默认数据库(转载)
我的操作系统为centos6.5 1 首先选择django要使用什么数据库.django1.10默认数据库为sqlite3,本人想使用mysql数据库,但为了测试方便顺便要安装一下sqlite开发包 ...
- Python3:Django根据models生成数据库表时报 __init__() missing 1 required positional argument: 'on_delete'
Python3:Django根据models生成数据库表时报 __init__() missing 1 required positional argument: 'on_delete' 一.分析 在 ...
- Python3:Django连接Mysql数据库时出错,'Did you install mysqlclient or MySQL-python?'
Python3:Django连接Mysql数据库时出错,'Did you install mysqlclient or MySQL-python?' 一.原因 因为Python版本问题,MySQLdb ...
- python学习笔记--Django入门三 Django 与数据库的交互:数据建模
把数据存取逻辑.业务逻辑和表现逻辑组合在一起的概念有时被称为软件架构的 Model-View-Controller (MVC)模式.在这个模式中, Model 代表数据存取层,View 代表的是系统中 ...
- Linux下安装Python3和django并配置mysql作为django默认服务器
我的操作系统为centos6.5 1 首先选择django要使用什么数据库.django1.10默认数据库为sqlite3,本人想使用mysql数据库,但为了测试方便顺便要安装一下sqlite开发包 ...
- windows下,python3安装django和mysql驱动
1.安装python3和django (1)Python 下载地址:https://www.python.org/downloads/ (2)Django 下载地址:https://www.djang ...
- python3.4连接mysql数据库的方法
python3.4连接mysql数据库的方法 发布时间:2014-08-04编辑:www.jbxue.com 本文介绍了python3.4连接mysql数据库的方法,在python3.4中不能用mys ...
- django 操作数据库--orm(object relation mapping)---models
思想 django为使用一种新的方式,即:关系对象映射(Object Relational Mapping,简称ORM). PHP:activerecord Java:Hibernate C#:Ent ...
- Python3实现连接SQLite数据库的方法
本文实例讲述了Python3实现连接SQLite数据库的方法,对于Python的学习有不错的参考借鉴价值.分享给大家供大家参考之用.具体方法如下: 实例代码如下: ? 1 2 3 4 5 6 7 8 ...
随机推荐
- AI将带我们走向何方?
AI即人工智能,对科幻着迷的博主对此认知颇深,打算从科幻电影入手,先讲下未来的AI将给人类带来哪些变化,哪些思考. 从最初的<星际航行>中的各种星球.地形等的介绍,到各个鉴于的探索,以及其 ...
- 洛谷 P1054 等价表达式 解题报告
P1054 等价表达式 题目描述 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的 ...
- /dev/null与/dev/zero区别
/dev/null和/dev/zero的区别 /dev/null,外号叫无底洞,你可以向它输出任何数据,它通吃,并且不会撑着! /dev/zero,是一个输入设备,你可你用它来初始化文件.该设备无穷尽 ...
- 构建MySQL-Cluster
Mysql Cluster概述与部署MySQL Cluster 是一种技术,该技术允许在无共享的系统中部署“内存中”数据库的 Cluster .通过无共享体系结构,系统能够使用廉价的硬件,而且对软硬件 ...
- SPI、I2C、UART三种串行总线协议的区别
第一个区别当然是名字: SPI(Serial Peripheral Interface:串行外设接口); I2C(INTER IC BUS) UART(Universal Asynchronous R ...
- 使用“DiskGenius”精确隐藏硬盘坏道
现在大家手中可能都有些有坏道的硬盘,也可能现在机器上的硬盘也出问题了.硬盘有坏道,肯定不会全部都是坏道,不能使用了.但我们因此而不能使用了,那么就太可惜了.所以,只要把有坏道的区域隐藏起来,就如同使用 ...
- JAVA8给我带了什么——Optional和CompletableFuture
不管是JAVA,还是.NET.我们常常会看到空异常(NullPointerException).这种异常都是在运行的过程中出现.往往是变量是一个null值.但是你引用这个变量的后继字段或是方法.所以我 ...
- 关于:HTTP Header -> Content-Type: text/plain Cache-Control: no-cache IE浏览器弹出错误下载对话
下午遇到一个很奇怪的现象,一个网址: http://192.168.1.3/login?action=a&fr=b.com 注意网址后面的参数形式,action参数在前,最后一个参数值的尾部含 ...
- hdu 3966(树链剖分+线段树区间更新)
传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...
- Top sort 双队列
#include<iostream> #include<vector> #include<queue> using namespace std; ]; int ma ...