如何在Django中配置双数据库,实现业务展示数据与系统内置表的分离存储?
当然可以实现!我之前帮同事处理过几乎一模一样的需求,下面是一步步的实操方案,亲测有效:
解决方案
1. 配置双数据库(settings.py)
首先在项目的settings.py里定义两个数据库连接:默认的default用来存储Django系统内置表(比如auth、admin、session等),另一个比如叫business_db专门存储看板业务数据。示例配置如下:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 替换为你使用的数据库引擎(如postgres、sqlite3) 'NAME': 'django_system_db', 'USER': 'db_user', 'PASSWORD': 'db_pass', 'HOST': 'localhost', 'PORT': '3306', }, 'business_db': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'dashboard_business_db', 'USER': 'db_user', 'PASSWORD': 'db_pass', 'HOST': 'localhost', 'PORT': '3306', } }
2. 自定义数据库路由(核心!)
Django默认会把所有模型的迁移操作应用到指定数据库,所以我们需要写一个路由规则,让系统内置模型只走default数据库,业务模型只走business_db。
在项目根目录创建routers.py文件,内容如下:
class BusinessDBRouter: def db_for_read(self, model, **hints): # 业务app的模型读操作走business_db if model._meta.app_label == 'dashboard': # 替换成你的业务app名称 return 'business_db' # 其他系统内置模型走default return 'default' def db_for_write(self, model, **hints): # 业务app的模型写操作走business_db if model._meta.app_label == 'dashboard': return 'business_db' return 'default' def allow_migrate(self, db, app_label, model_name=None, **hints): # 控制迁移逻辑:业务app仅在business_db执行迁移 if app_label == 'dashboard': return db == 'business_db' # 系统内置app仅在default执行迁移,禁止在business_db创建系统表 if db != 'default': return False return True
然后在settings.py中添加这个路由配置:
DATABASE_ROUTERS = ['your_project_name.routers.BusinessDBRouter'] # 替换为你的项目名称
3. 执行迁移操作(关键步骤,别搞错顺序!)
- 第一步:迁移系统内置表到
default数据库,直接执行默认migrate命令即可:
python manage.py migrate
这一步会把auth、admin、session等系统表全部创建到default对应的数据库中,完全符合你的需求。
- 第二步:仅迁移业务app的模型到
business_db,必须指定业务app名称(绝对不能直接用migrate --database=business_db,否则会把系统模型也迁过去):
python manage.py migrate dashboard --database=business_db # 替换为你的业务app名称
如果有多个业务app,就逐个执行该命令,比如python manage.py migrate app1 --database=business_db。
4. 验证效果
完成迁移后,你可以通过两种方式确认结果:
- 用数据库客户端(如Navicat、DBeaver)查看:
django_system_db里只有系统内置表,dashboard_business_db里只有你业务app的模型表,无任何系统表。 - 进入Django Shell测试读写:
python manage.py shell
然后执行以下代码验证:
from django.contrib.auth.models import User User.objects.all() # 从default数据库读取系统用户表 from dashboard.models import YourBusinessModel YourBusinessModel.objects.all() # 从business_db读取业务表
注意事项
- 后续新增业务模型时,只需在业务app中编写模型,执行
makemigrations后,再用migrate dashboard --database=business_db迁移即可,不会影响系统数据库。 - 如果有多个业务app,可在路由的
app_label判断中添加所有业务app名称,或写更灵活的规则(比如判断app_label是否以dashboard_前缀开头)。 - 若之前误将系统表迁到了业务数据库,可先删除业务库中的系统表,再重新执行上述迁移步骤。
内容的提问来源于stack exchange,提问作者orr
相关产品推荐
相关产品推荐

