You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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']

问题根源与解决方案

核心问题

  1. Meta类大小写错误:Django仅识别大写的class Meta:,原代码中class meta:会被框架忽略,导致db_table配置不生效。
  2. 无效配置项:模型Meta类中不存在db_router参数,路由配置应放在settings.py的DATABASE_ROUTERS中。
  3. 字段语法错误:models.IntegerField缺少括号,未正确实例化字段。

修正步骤

  1. 修正Meta类名称:将所有模型中的class meta:改为class Meta:。
  2. 移除无效配置:删除Meta类中的db_router项,确保settings.py中配置了DATABASE_ROUTERS。
  3. 修正字段定义:给IntegerField补全括号,改为models.IntegerField()。
  4. 重新生成迁移:删除各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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 13:34:58