Django 1.11自定义数据库路由后,migrate指定数据库执行失败求助
解决Django 1.11自定义数据库路由在migrate时的失效问题
这个问题我之前帮朋友排查过,核心原因其实很直白:migrate这类命令行数据库操作完全不经过HTTP请求流程,你原来依赖URL域名(比如customer1.example.com)的路由逻辑,根本拿不到请求的Host信息,自然就失效了——哪怕你用--database指定了数据库,路由还是会因为找不到Host而乱报错。
怎么改?核心是区分「HTTP请求场景」和「命令行场景」
我们需要给你的数据库路由类加个“开关”:当检测到是命令行操作时,就跳过基于Host的路由逻辑,乖乖尊重--database参数;当是正常HTTP请求时,继续用原来的域名匹配逻辑。
1. 优化路由类的场景判断
假设你之前是通过中间件把请求Host存到线程本地变量里的,那现在要在路由类里加个判断:如果是命令行操作,直接返回None,让Django自己处理默认库或者你指定的数据库。
直接修改你的路由类就行,示例代码如下:
import threading from django.conf import settings import sys # 线程本地存储,用来存当前请求的Host thread_local = threading.local() class CustomerDatabaseRouter: def _is_cli_command(self): # 判断是不是命令行操作:把常用的数据库命令都列进来 return len(sys.argv) > 1 and sys.argv[1] in ['migrate', 'shell', 'dumpdata', 'loaddata'] def db_for_read(self, model, **hints): # 如果是命令行场景,直接返回None,让Django用--database指定的库 if self._is_cli_command(): return None # HTTP请求场景,继续用原来的域名匹配逻辑 if hasattr(thread_local, 'host'): host = thread_local.host # 从域名里提取客户标识,比如customer1.example.com -> customer1 customer_db = host.split('.')[0] if customer_db in settings.DATABASES: return customer_db # 兜底返回None,使用默认数据库 return None def db_for_write(self, model, **hints): # 读和写逻辑保持一致即可 if self._is_cli_command(): return None if hasattr(thread_local, 'host'): host = thread_local.host customer_db = host.split('.')[0] if customer_db in settings.DATABASES: return customer_db return None def allow_relation(self, obj1, obj2, **hints): # 只允许同一个数据库内的模型建立关联 db1 = obj1._state.db db2 = obj2._state.db if db1 and db2 and db1 == db2: return True return None def allow_migrate(self, db, app_label, model_name=None, **hints): # 迁移时仅允许指定的数据库执行操作 # 当你用--database=customer1时,db参数就是customer1 if db in settings.DATABASES: return True return False
2. 验证修改效果
改完之后,再执行migrate命令试试:
python manage.py migrate --database=customer1
这时候路由会识别到是命令行操作,直接跳过Host匹配逻辑,Django就会老老实实使用你指定的customer1数据库执行迁移了。
额外提醒
- 确保你的
settings.DATABASES里已经正确配置了customer1、customer2这些数据库,名字要和域名里的标识完全对应。 - 如果有些模型是某个客户专属的,记得在
allow_migrate里再加一层判断,避免把客户专属模型误迁移到其他数据库里。
内容的提问来源于stack exchange,提问作者Chris Burrus
相关产品推荐
相关产品推荐

