Django单应用/模型迁移至多数据库仅单库生效问题咨询
问题原因
- 路由匹配优先级问题:Django会按照
DATABASE_ROUTERS配置的顺序依次调用路由方法,只要某一个路由返回非None结果,就会终止后续路由的匹配逻辑。当前配置中VIGRouter排在前面,处理izLogApp的迁移校验时,直接返回仅db_vig允许迁移,后续VISRouter等同应用的路由不会被执行,导致其他数据库的izLogApp模型迁移被直接拒绝。 - 默认迁移命令逻辑限制:Django的
migrate命令默认不会自动遍历所有配置的数据库执行迁移,仅会作用于指定的单数据库,未显式指定的数据库不会执行模型同步操作。 - 路由的
allow_migrate逻辑不符合需求:现有每个业务路由的allow_migrate仅允许对应单库迁移izLogApp,和同步到所有库的需求冲突。
解决方法
步骤1:调整数据库路由配置
新增专门的全局迁移路由,放在DATABASE_ROUTERS列表的最前面,用于统一处理izLogApp的多库迁移校验,原有业务路由仅保留读写路由逻辑即可。
新增全局迁移路由代码示例:
class GlobalMigrateRouter: route_app_labels = {'izLogApp'} # 所有需要同步izLogApp模型的数据库列表 allowed_migrate_dbs = {'izlog', 'db_vig', 'db_vis'} def allow_migrate(self, db, app_label, model_name=None, **hints): if app_label in self.route_app_labels: return db in self.allowed_migrate_dbs # 其他应用的迁移逻辑保持原有路由的处理逻辑 return None
修改settings.py的路由配置:
DATABASE_ROUTERS = [ # 迁移路由放在最优先位置 'routers.db_routers.GlobalMigrateRouter', 'routers.db_routers.AuthRouter', 'routers.db_routers.VIGRouter', 'routers.db_routers.VISRouter', 'routers.db_routers.DURRouter', 'routers.db_routers.IPCRouter', ]
调整原有业务路由:
删除VIGRouter、VISRouter等业务路由中的allow_migrate方法,或者将其返回值改为None,避免拦截迁移校验逻辑,这些路由仅负责读写请求的数据库分配即可。
步骤2:按数据库单独执行迁移命令
需要为每个配置的业务数据库单独执行迁移操作,通过--database参数指定目标数据库:
# 同步到izlog库 python manage.py migrate --database=izlog # 同步到db_vig库 python manage.py migrate --database=db_vig # 同步到db_vis库 python manage.py migrate --database=db_vis
如果需要简化操作,可以编写shell脚本批量执行所有数据库的迁移命令。
内容的提问来源于stack exchange,提问作者reda benyoub
相关产品推荐
相关产品推荐

