前一段在学习过程中,想的都比较简单,所以就只有一个应用一个数据库,但是当写的东西多了就发觉不同功能应该由不同应用来处理,不同应用可以使用单独使用自己的数据库,这样比较利于网站的扩展。原谅我,比较懒,所以废话就少说吧。
首先,假定项目名为test,有两个应用,user用于管理用户,essay用于管理文章。
python manage.py startapp userApp python manage.py startapp essayApp
#userApp的models.py中 from django.db import models class User(models.Model): name = models.CharField(max_length=30)
#essayApp中的models.py中 from django.db import models from userApp.models import User class Essay(models.Model): owner = models.ForeignKey(User,related_name="essay_owner") content = models.TextField()
在settings.py中为两个应用注册
INSTALLED_APPS = ( #原来系统默认存在的我就略去不说了…… 'userApp', 'essayApp', )
添加将要使用的数据库
DATABASES = { #之所以这里仍然保留default数据库,是因为如果要使用Django的Auth应用或者Admin应用 #我希望它默认将数据存放在default.db中,而不与其他数据搞混,当然也可以额外指定,后边会说 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': 'db/default.db', 'USER': '', 'PASSWORD': '', 'HOST': '', 'PORT': '', }, #提供给userApp使用 'userdb': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': 'db/user.db', 'USER': '', 'PASSWORD': '', 'HOST': '', 'PORT': '', }, #提供给essayApp使用 'essaydb': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': 'db/essay.db', 'USER': '', 'PASSWORD': '', 'HOST': '', 'PORT': '', }, }
就目前工作来说,还没完成,如果执行python manage.py syncdb 则会看到userApp_User和essayApp_Essay两张表都建在了default.db中,因为我们虽然添加了两个数据库配置,但是还没指定哪一个应用使用哪一个数据库,因此都使用了默认数据库配置 ‘default’
新建一个dbsetings.py
class appdb(object): def db_for_read(self, model, **hints): #该方法定义读取时从哪一个数据库读取 return self.__app_router(model) def db_for_write(self, model, **hints): #该方法定义写入时从哪一个数据库读取,如果读写分离,可再额外配置 return self.__app_router(model) def allow_relation(self, obj1, obj2, **hints): #该方法用于判断传入的obj1和obj2是否允许关联,可用于多对多以及外键 #同一个应用同一个数据库 if obj1._meta.app_label == obj2._meta.app_label: return True #User和Essay是允许关联的 elif obj1._meta.app_label in ('userApp','essayApp') and #接上一行 obj2._meta.app_label in ('userApp','essayApp'): return True def allow_syncdb(self, db, model): #该方法定义数据库是否能和名为db的数据库同步 return self.__app_router(model) == db #添加一个私有方法用来判断模型属于哪个应用,并返回应该使用的数据库 def __app_router(self, model): if model._meta.app_label == 'userApp': return 'userdb' elif model._meta.app_label == 'essayApp': return 'essaydb' else : return 'default'
DATABASE_ROUTERS = ['dbsettings.appdb']
至此,工作基本完毕。
但是要注意的是必须单独为每一个数据库同步,即
python manage.py syncdb #默认同步的数据库为'default' python manage.py syncdb --database=userdb #为userdb同步数据 python manage.py syncdb --database=essaydb #为essaydb同步数据
关于不同数据库之间多对多和外键的查询,我明天再更新!
昨天本以为实现了不同数据库之间多对多的查询,外键可以正常访问,多对多今天研究半天都没有成功,查询Django官方文档,发现明确写着
Django目前不提供外键或多对多的关系跨越多个数据库的支持。如果你使用路由器分割模型对不同的数据库,任何FOREIGNKEY和多对多关系的模型定义必须是单个数据库的内部。
然而,如果你使用SQLite或MySQL,MyISAM,没有强制引用完整性;作为结果,你可以'假'跨数据库外键。然而,这样的配置是不由Django官方支持。原来我渣一般的爬文水平,以上引用是机械翻译过来的……
原文:
https://docs.djangoproject.com/en/1.4/topics/db/multi-db/
参看链接页面最底部
不过跨数据库之间的多对多和外键可以由自己实现,要写SQL语句,比较麻烦,我也不是很擅长,暂时研究到这
我还是研究出了一种方法,详情请看学习笔记(7)
转载请注明出处,谢谢!