在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‘: ‘3306‘,‘OPTIONS‘: { ‘init_command‘: "SET sql_mode=‘STRICT_TRANS_tableS‘",},#MysqL使用严格模式,不指定会有警告信息 },‘db2‘:{ ‘ENGINE‘: ‘django.db.backends.MysqL‘,‘name‘: ‘db2‘,}
如果访问没有在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.Jsonpython manage.py dumpdata app02 --database=db2 > app2_fixture.Jsonpython manage.py dumpdata auth > auth_fixture.Json
多个数据库导入:
python manage.py loaddata app1_fixture.Json --database=db1python manage.py loaddata app2_fixture.Json --database=db23、自动数据库路由
使用多个数据库时最简单的方法是设置数据库路由方案,以保证对象对原始数据库的“粘性",默认所有的查询都会返回到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:utf8from django.conf import settingsDATABASE_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,**hints): if model._Meta.app_label in DATABASE_MAPPing: return DATABASE_MAPPing[model._Meta.app_label] return None def allow_relation(self,obj1,**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,**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 modelsclass 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总结
以上是内存溢出为你收集整理的Django使用多数据库For python3全部内容,希望文章能够帮你解决Django使用多数据库For python3所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)