项目使用环境:
- Python3.6.3
- Django==2.0.6
- Sqlite3
第一步:配置settings.py文件
# 这里是主配置我只是把我的配置贴出来(自己要对应上自己的项目)
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'authpermission',
'webshow',
'captcha',
'commons',
'accounts',
'django_celery_results',
'webshielddata'
]
################################################
# #
# database Configuration #
# #
################################################
DATABASES = {
'default': {},
"webshield_web_db": {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(DBS_DIR, "webshield_web.db"),
},
"webshield_db": {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(DBS_DIR, "webshield.db"),
}
}
DATABASE_ROUTERS = ['commons.database_router.Webshieldauthrouter']
DATABASE_APPS_MAPPING = {
# Example
# appname : database
"admin": "webshield_web_db",
"auth": "webshield_web_db",
"contenttypes": "webshield_web_db",
"sessions": "webshield_web_db",
"accounts": "webshield_web_db",
"authpermission": "webshield_web_db",
"webshow": "webshield_web_db",
"webshielddata": "webshield_db",
}
"default": Django默认选择使用的数据库、这里设置为空
"webshield_web_db": 数据库一
"webshield_db": 数据库二
"DATABASE_ROUTERS": 数据库路由配置配置内容见database_router.py文件,配置的路径为database_router.py文件的路径
"DATABASE_APPS_MAPPING": 数据库与app做映射,每个app对应使用的数据库
appname: 在主配置文件中INSTALLED_APPS列表中的名
注意:为了使django自己的表也创建到你自己定义的数据库中,你可以指定 : admin, auth, contenttypes, sessions 到设定的数据库中,如果不指定则会自动创建到默认(default)的数据库中.
第二步:创建database_router.py文件(此文件名可以自己随意起)
我的路径是: commons/database_router.py,此路径DATABASE_ROUTERS会使用
from django.conf import settings
DATABASE_MAPPING = settings.DATABASE_APPS_MAPPING
class Webshieldauthrouter(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):
"""
表一(obj1)与表二(obj2)是否可以产生关联
"""
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_migrate(self, db, app_label, model_name=None, **hints):
"""
确定migrate操作是否可以在别名为db的数据库上运行
"""
if db in DATABASE_MAPPING.values():
return DATABASE_MAPPING.get(app_label) == db
elif app_label in DATABASE_MAPPING:
return False
return None
解释:
db_for_read():每个app从哪个数据库读取数据
db_for_write(): 每个app写数据写入那个数据库
allow_relation(): 允许同一数据库中每个app的表之间差生关系(Foreignkey, OneToOneField, ManyToManyField)
allow_migrate(): 确定migrate操作统一,要app与对应映射的数据库统一
第三步: django创建表例子
project_name(项目名)/appname1(app名)/models.py
from django.db import models
class Webshield_data(models.Model):
"""
硬件提供数据表
"""
access_id = models.IntegerField(
verbose_name="访客id",
null=True
)
def __unicode__(self):
return self.id
class Meta:
app_label = "webshielddata" # 这里很重要,是settings.py中INSTALLED_APPS列表对应的数据
db_table = "webshield_data"
verbose_name = "硬件提供数据"
verbose_name_plural = verbose_name
提示:此表数据会存入webshield_db数据库
project_name(项目名)/appname2(app名)/models.py
from django.db import models
class data1(models.Model):
"""
硬件提供数据表
"""
name = models.Charfield(
verbose_name="名称",
max_length=521,
null=True
)
def __unicode__(self):
return self.name
class Meta:
app_label = "accounts" # 这里很重要,是settings.py中INSTALLED_APPS列表对应的数据
db_table = "data1"
verbose_name = "测试数据"
verbose_name_plural = verbose_name
提示:此表数据会存入webshield_web_db数据库
第四步:生成数据表
python3 manage.py makemigrations
# 创建表app对应的表到webshield_web_db数据库中
python3 manage.py migrate --database=webshield_web_db
# 创建表app对应的表到webshield_db数据库中
python3 manage.py migrate --database=webshield_db
# 创建表app对应的表到default数据库中(如果default配置存在)
python3 manage.py migrate
注意:与此相应的,dbshell,dumpdata,loaddata命令都有--database选项。
指定数据表导出:
python3 manage.py dumpdata app1.modelname --database=db1 > app1_fixture.json
python3 manage.py dumpdata app2.modelname --database=db2 > app2_fixture.json
第五步:使用CURD时注意事项
查询:
#### 查询(select)
# 查询 'default' 数据库.
Author.objects.all()
# 查询 'default' 数据库.
Author.objects.using('default').all()
# 查询 'webshield_web_db' 数据库.
Author.objects.using('webshield_web_db').all()
第一种添加方式:
#### 添加
my_object.save(using='webshield_web_db')
第二种添加方式:
#### 保存
p = Person(name='Fred')
p.save(using='first') # (statement 1)
p.save(using='second') # (statement 2)
注意:第二种添加方式的代码会产生问题,当p在first数据库中第一次保存时,会默认生成一个主键,这样使用second数据库保存时,p已经有了主键,这个主键如果未被使用不会产生问题,但如果先前被使用了,就会覆盖原先的数据。
主键冲突问题解决办法:
解决方案一:
#### 解决办法一
p = Person(name='Fred')
p.save(using='first')
p.pk = None # Clear the primary key.
p.save(using='second') # Write a completely new object.
解决方案二:
#### 解决办法二
p = Person(name='Fred')
p.save(using='first')
p.save(using='second', force_insert=True)
删除:
u = User.objects.using('webshield_web_db').get(username='fred')
u.delete() # 从 `webshield_web_db` 库删除
将对象从B数据库移动到A数据库:
user_obj.save(using='A')
user_obj.delete(using='B')
总结:以上内容不仅仅是针对sqlite数据库、同时也适用mysql;