Django多数据库路由问题:自定义模型未同步至数据库
多数据库路由下自定义模型未同步至对应数据库问题排查
尝试使用Django数据库路由实现多数据库功能,但自定义模型未同步至对应数据库,仅Django自带模型存在,自定义表未生成。
相关代码文件
models.py
from django.db import models from django.contrib.auth.models import User # 多余导入peewee和psycopg2已移除 # Create your models here. class temp(models.Model): id= models.IntegerField(primary_key=True) class Meta: app_label='client_db' # 此处错误:app_label应为应用名称而非数据库别名 db_table='temp' class temp2(models.Model): id= models.IntegerField(primary_key=True) class Meta: app_label='default' # 此处错误:app_label应为应用名称而非数据库别名 db_table='temp2'
settings.py
DATABASE_ROUTERS = ('app_celery.dbrouter.client_router',) DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', }, 'client_db': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'amm', 'USER': 'xxxx', 'PASSWORD': 'xxxx', 'HOST': '127.0.0.1', 'PORT': 5432, }, }
dbrouter.py
class client_router: """ A router to control all database operations on models in the user application. """ def db_for_read(self, model, **hints): if model._meta.app_label == 'client_db': return 'client_db' return 'default' def db_for_write(self, model, **hints): if model._meta.app_label == 'client_db': return 'client_db' return 'default' def allow_relation(self, obj1, obj2, **hints): if obj1._meta.app_label == 'client_db' or \ obj2._meta.app_label == 'client_db': return True return False def allow_migrate(self, db, app_label, model_name=None, **hints): if app_label == 'client_db': return db == 'client_db' return False # 此处错误:阻止了所有非client_db应用的迁移,包括自定义应用和Django自带应用的正常迁移
已执行的迁移命令
python3 manage.py makemigrations python3 manage.py migrate python3 manage.py migrate --database=client_db
问题排查与解决方案
1. 修正模型的app_label配置
app_label指定的是模型所属的Django应用名称(比如你的应用是app_celery),而非数据库别名。修改models.py中的Meta类:
class temp(models.Model): id= models.IntegerField(primary_key=True) class Meta: app_label='app_celery' # 改为实际应用名称 db_table='temp' class temp2(models.Model): id= models.IntegerField(primary_key=True) class Meta: app_label='app_celery' # 改为实际应用名称 db_table='temp2'
2. 修正路由的allow_migrate方法逻辑
当前方法阻止了非client_db应用的所有迁移,导致自定义模型和部分Django自带模型无法正常迁移。修改为按模型或应用规则分配:
def allow_migrate(self, db, app_label, model_name=None, **hints): # 处理自定义应用的模型路由 if app_label == 'app_celery': model = hints.get('model') # 根据模型表名分配数据库 if model and model._meta.db_table == 'temp': return db == 'client_db' elif model and model._meta.db_table == 'temp2': return db == 'default' return False # 允许Django自带核心应用在default数据库迁移 if app_label in ['auth', 'admin', 'contenttypes', 'sessions']: return db == 'default' # 其他应用默认不允许迁移 return False
3. 修正迁移命令执行方式
必须指定应用名称生成迁移文件,否则可能无法识别自定义模型:
# 生成自定义应用的迁移文件 python3 manage.py makemigrations app_celery # 将temp2模型迁移到default数据库 python3 manage.py migrate app_celery --database=default # 将temp模型迁移到client_db数据库 python3 manage.py migrate app_celery --database=client_db
4. 清理无关导入
移除models.py中与Django模型无关的导入:from peewee import *和import psycopg2,避免潜在冲突。
内容的提问来源于stack exchange,提问作者Kirti Purohit
相关产品推荐
相关产品推荐

