Django中避免应用名称追加到PostgreSQL表名的问题求助
Django多数据库路由下自定义表名不生效问题解决
问题描述
在Django中实现数据库路由,将两个应用的数据分别存储到不同PostgreSQL数据库,但遇到应用名称被自动追加到表名的问题。尝试通过Model的Meta类设置db_table指定自定义表名,但未生效,期望数据库中仅显示设置的自定义表名。
相关代码(原错误版本)
App1 - models.py
from django.db import models class sample_table1(models.Model): id = models.IntegerField col1 = models.CharField(max_length=100) col2 = models.CharField(max_length=50, null=True) col3 = models.CharField(max_length=200, null=True) class meta: db_table = 'Sample_DB1' db_router = 'router.MyDBRouter.MyDB_Router' app_label = 'app1' def __str__(self): return f"{self.id}, {self.col1}" class sample_table2(models.Model): id = models.IntegerField col1 = models.CharField(max_length=100) class meta: db_table = 'Sample_DB2' db_router = 'router.MyDBRouter.MyDB_Router' app_label = 'app1' def __str__(self): return f"{self.id}, {self.col1}" class sample_table3(models.Model): id = models.IntegerField col1 = models.CharField(max_length=100) class meta: db_table = 'Sample_DB3' db_router = 'router.MyDBRouter.MyDB_Router' app_label = 'app1' def __str__(self): return f"{self.id}, {self.col1}"
App2 - models.py
from django.db import models class tbl2(models.Model): id = models.IntegerField col22 = models.CharField(max_length=100) col33 = models.CharField(max_length=10, null=True) class meta: db_table = 'Sample_tbl2' db_router = 'router.MyDBRouter.MyDB_Router' app_label = 'app2' def __str__(self): return f"{self.id}, {self.col1}"
数据库路由(router.py)
class MyDB_Router: def db_for_read(self, model, **hints): if model._meta.app_label == 'app1': return 'database1' elif model._meta.app_label == 'app2': return 'database2' return None def db_for_write(self, model, **hints): if model._meta.app_label == 'app1': return 'database1' elif model._meta.app_label == 'app2': return 'database2' return None def allow_relation(self, obj1, obj2, **hints): # 仅允许同一应用内的模型建立关联 return obj1._meta.app_label == obj2._meta.app_label def allow_migrate(self, db, app_label, model_name=None, **hints): # 将app1迁移到database1,app2迁移到database2 if app_label in ['app1', 'app2']: return db == 'database1' if app_label == 'app1' else db == 'database2' return None
settings.py(数据库配置)
DATABASES = { 'default': {}, 'database1': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'database1_name', 'USER': 'postgres', 'PASSWORD': 'abc123.', 'HOST': 'localhost', 'PORT': '5432', }, 'database2': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'database2_name', 'USER': 'postgres', 'PASSWORD': 'abc123.', 'HOST': 'localhost', 'PORT': '5432', }, } # 需添加路由配置(原代码遗漏) DATABASE_ROUTERS = ['router.MyDB_Router']
问题根源与解决方案
核心问题
- Meta类大小写错误:Django仅识别大写的
class Meta:,原代码中class meta:会被框架忽略,导致db_table配置不生效。 - 无效配置项:模型Meta类中不存在
db_router参数,路由配置应放在settings.py的DATABASE_ROUTERS中。 - 字段语法错误:
models.IntegerField缺少括号,未正确实例化字段。
修正步骤
- 修正Meta类名称:将所有模型中的
class meta:改为class Meta:。 - 移除无效配置:删除Meta类中的
db_router项,确保settings.py中配置了DATABASE_ROUTERS。 - 修正字段定义:给
IntegerField补全括号,改为models.IntegerField()。 - 重新生成迁移:删除各app下
migrations目录中除__init__.py外的所有文件,执行以下命令:python manage.py makemigrations python manage.py migrate --database=database1 python manage.py migrate --database=database2
修正后的模型示例(App1 sample_table1)
from django.db import models class sample_table1(models.Model): id = models.IntegerField() col1 = models.CharField(max_length=100) col2 = models.CharField(max_length=50, null=True) col3 = models.CharField(max_length=200, null=True) class Meta: db_table = 'Sample_DB1' app_label = 'app1' def __str__(self): return f"{self.id}, {self.col1}"
内容的提问来源于stack exchange,提问作者Obtuse
相关产品推荐
相关产品推荐

