一、先明确你的数据库配置结构
首先确认你在 settings.py 中的 DATABASES 配置格式(示例如下),假设第二个数据库的别名是 db2(你可以替换成自己的别名,比如 secondary):
# settings.py
DATABASES = {
# 第一个默认数据库(别名 default)
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db1',
'USER': 'root',
'PASSWORD': '123456',
'HOST': 'localhost',
'PORT': '3306',
},
# 第二个数据库(别名 db2)
'db2': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db2',
'USER': 'root',
'PASSWORD': '123456',
'HOST': 'localhost',
'PORT': '3306',
}
}
二、场景1:全局默认切换到第二个数据库
如果你想让整个项目默认使用第二个数据库(所有未指定库的操作都走 db2),直接修改 DATABASES 中 default 的配置为第二个库的信息即可:
# 修改后的 settings.py
DATABASES = {
# 将 default 指向原来的第二个数据库
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db2', # 原 db2 的库名
'USER': 'root',
'PASSWORD': '123456',
'HOST': 'localhost',
'PORT': '3306',
},
# 原第一个数据库(可选保留,别名可自定义)
'db1': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db1',
'USER': 'root',
'PASSWORD': '123456',
'HOST': 'localhost',
'PORT': '3306',
}
}
修改后重启项目,所有 ORM 操作(如 Model.objects.all())都会默认使用第二个数据库。
三、场景2:仅指定操作使用第二个数据库(推荐,不影响全局)
如果不想改变全局默认库,只是部分操作(如查询/新增数据)使用第二个数据库,有 3 种常用方式:
方式1:单个查询/操作指定数据库
使用 using() 方法指定要使用的数据库别名(如 db2),适用于零散的操作:
# 示例:查询 User 模型的数据,使用 db2 数据库
from django.contrib.auth.models import User
# 查询
users = User.objects.using('db2').all()
# 新增
user = User(username='test', email='test@xxx.com')
user.save(using='db2') # 保存到 db2
# 更新
User.objects.using('db2').filter(id=1).update(username='new_name')
# 删除
User.objects.using('db2').filter(id=1).delete()
方式2:模型类默认使用第二个数据库
如果某个模型始终要使用第二个数据库,可在模型类中定义 using 方法:
# models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=10, decimal_places=2)
# 重写 using 方法,指定默认使用 db2
def using(self, alias=None):
return super().using(alias or 'db2')
# 使用时无需手动指定 using,默认走 db2
product = Product(name='手机', price=2999)
product.save() # 自动保存到 db2
products = Product.objects.all() # 自动从 db2 查询
方式3:使用数据库路由(适用于多模型批量指定)
如果多个模型需要统一使用第二个数据库,可配置数据库路由(推荐大型项目):
-
在项目中创建
routers.py文件:# routers.py class DB2Router: """路由类:指定模型使用 db2 数据库""" # 需要使用 db2 的模型列表(替换为你的模型路径) db2_models = ['app1.models.Product', 'app2.models.Order'] def db_for_read(self, model, **hints): """读操作指定数据库""" model_path = f"{model.__module__}.{model.__name__}" if model_path in self.db2_models: return 'db2' return 'default' # 其他模型用默认库 def db_for_write(self, model, **hints): """写操作指定数据库""" model_path = f"{model.__module__}.{model.__name__}" if model_path in self.db2_models: return 'db2' return 'default' def allow_relation(self, obj1, obj2, **hints): """允许关联关系""" return True def allow_migrate(self, db, app_label, model_name=None, **hints): """允许迁移""" return True# routers.py(比较完善) from django.apps import apps class UniversalDatabaseRouter: """ 通用数据库路由类:支持多库配置,可批量/全部指定模型 配置说明: - key:数据库别名(如 'db2') - value:模型列表(['app1.models.Model1'])或 '__all__'(表示全部模型) """ # 核心配置:数据库别名 → 对应模型(支持__all__表示全部模型) DB_MODEL_MAP = { # 示例1:第二个数据库(db2)接管全部模型 'db2': '__all__', # 示例2:部分模型映射到其他数据库(按需开启) # 'db3': ['app2.models.Order', 'app3.models.Product'], # 示例3:默认库(default)接管剩余未配置的模型(无需写) } def _get_db_alias_for_model(self, model): """核心辅助方法:根据模型获取对应的数据库别名""" # 拼接模型的完整路径(如 'app1.models.User') model_full_path = f"{model.__module__}.{model.__name__}" # 遍历配置,匹配模型对应的数据库 for db_alias, model_config in self.DB_MODEL_MAP.items(): # 配置为 __all__ → 全部模型都用该数据库 if model_config == '__all__': return db_alias # 配置为模型列表 → 匹配到则返回对应数据库 if model_full_path in model_config: return db_alias # 未匹配到 → 使用默认数据库 return 'default' def db_for_read(self, model, **hints): """读操作:返回模型对应的数据库别名""" return self._get_db_alias_for_model(model) def db_for_write(self, model, **hints): """写操作:返回模型对应的数据库别名(和读保持一致)""" return self._get_db_alias_for_model(model) def allow_relation(self, obj1, obj2, **hints): """允许关联关系:只要两个对象的数据库相同,就允许关联""" db1 = self._get_db_alias_for_model(obj1.__class__) db2 = self._get_db_alias_for_model(obj2.__class__) return db1 == db2 def allow_migrate(self, db, app_label, model_name=None, **hints): """ 允许迁移:控制模型是否能在指定数据库上执行 migrate - db:当前要迁移的数据库别名 - model_name:模型名(如 'user') """ # 无模型名 → 允许迁移 if not model_name: return True # 获取模型类(通过app_label和model_name) try: model = apps.get_model(app_label, model_name) except LookupError: return False # 模型对应的数据库 == 当前迁移的数据库 → 允许迁移 target_db = self._get_db_alias_for_model(model) return db == target_db def allow_migrate_model(self, db, model): """Django 4.2+ 新增方法:细化模型迁移权限(兼容用)""" target_db = self._get_db_alias_for_model(model) return db == target_db需求场景 配置方式(修改 DB_MODEL_MAP)全部模型用第二个数据库(db2) 'db2': '__all__'部分模型用 db2 'db2': ['app1.models.Product', 'app2.models.Order']多数据库分别映射不同模型 'db2': ['app1.models.A'], 'db3': ['app2.models.B'] -
在
settings.py中注册路由:# settings.py DATABASE_ROUTERS = ['项目名.routers.DB2Router'] # 替换为你的 routers.py 路径
配置后,db2_models 中的模型会自动使用 db2 数据库,其他模型仍用默认库。
四、验证是否切换成功
可以通过以下方式确认操作是否走第二个数据库:
-
查看数据库日志(如 MySQL 日志),确认 SQL 语句执行的库名;
-
在第二个数据库中手动新增一条测试数据,用代码查询验证是否能获取到。
总结
-
全局切换:直接修改
settings.py中DATABASES['default']为第二个库的配置,简单但影响所有操作; -
局部切换:零散操作用
using('db2'),单个模型重写using方法,多模型用数据库路由(推荐); -
核心关键:所有指定操作的核心是第二个数据库的别名(如示例中的
db2),需与settings.py




没有回复内容