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

Django多数据库配置后执行createsuperuser报缺少ENGINE值错误如何解决

错误原因

  1. 数据库路由缺失db_for_write方法,且重复定义db_for_read:两个路由类中均重复定义了两次读路由逻辑,完全没有实现写操作的路由规则,Django处理写请求时无法匹配到对应数据库,就会默认路由到default库,而你的default库为空配置,直接触发报错。
  2. allow_migrate方法返回值不符合规范:该方法要求返回布尔值(True/False/None)表示是否允许在指定数据库执行迁移,你直接返回了数据库名字符串,导致路由判断逻辑完全失效,迁移和运行时的路由匹配都会出错。
  3. 自定义用户管理器保存逻辑冲突:你在create_user中手动指定了using="users_db",但create_superuser调用完create_user后又执行了一次user.save(using=self._db),这里的self._db如果没有正确初始化,会落到默认库;同时从报错回溯可以看到create_user中实际执行的是不带using参数的user.save(),说明实际运行代码的保存参数被覆盖,进一步导致路由匹配失效。

解决方案

1. 修正数据库路由代码

删除重复的db_for_read定义,新增db_for_write方法,同时修正allow_migrate的返回值:

class AuthRouter:
    route_app_labels = {'sessions', 'auth', 'contenttypes', 'admin', 'accounts'}

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'users_db'
        return None

    # 新增写路由逻辑
    def db_for_write(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'users_db'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        if (
            obj1._meta.app_label in self.route_app_labels or
            obj2._meta.app_label in self.route_app_labels
        ):
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        # 仅当数据库为users_db且应用属于路由列表时才允许迁移
        if app_label in self.route_app_labels:
            return db == 'users_db'
        return None
    

class PersonalDBRouter:
    route_app_labels = {'actions', 'blog', 'token_blacklist', 'taggit', 'django_celery_beat', 'django_celery_results',}

    def db_for_read(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'content_db'
        return None

    # 新增写路由逻辑
    def db_for_write(self, model, **hints):
        if model._meta.app_label in self.route_app_labels:
            return 'content_db'
        return None

    def allow_relation(self, obj1, obj2, **hints):
        if (
            obj1._meta.app_label in self.route_app_labels or
            obj2._meta.app_label in self.route_app_labels
        ):
            return True
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        if app_label in self.route_app_labels:
            return db == 'content_db'
        return None

2. 修正自定义用户管理器的保存逻辑

避免重复保存,统一指定保存的数据库:

class MyAccountManager(BaseUserManager):
    def create_user(self, email, username, first_name, last_name, password=None):
        if not email:
            raise ValueError('Users must have an email address')
        if not username:
            raise ValueError('Users must have a username')
        if not first_name:
            raise ValueError('Users must have a First Name')

        user = self.model(
            email=self.normalize_email(email),
            username=username,
            first_name=first_name,
            last_name=last_name,
        )
        user.set_password(password)
        return user

    def create_superuser(self, email, username, first_name, last_name, password):
        user = self.create_user(
            email=self.normalize_email(email),
            password=password,
            username=username,
            first_name=first_name,
            last_name=last_name,
        )
        user.is_admin = True
        user.is_staff = True
        user.is_superuser = True
        # 统一指定保存到users_db,也可以依赖路由自动匹配
        user.save(using="users_db")
        return user

3. 可选兜底方案

如果调试阶段还是出现路由匹配问题,可以临时把default库指向users_db,避免路由失效时落到空库,等所有逻辑调试通顺后再改回空配置即可:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'users_db',
        'USER': 'postgres',
        'PASSWORD': 'Trial_user123',
        'HOST':'127.0.0.1',
        'PORT':'5432',
    },
    'users_db': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'users_db',
        'USER': 'postgres',
        'PASSWORD': 'Trial_user123',
        'HOST':'127.0.0.1',
        'PORT':'5432',
    },
    'content_db': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'content_II',
        'USER': 'postgres',
        'PASSWORD': 'Trial_user123',
        'HOST':'127.0.0.1',
        'PORT':'5432',
    },
}

内容的提问来源于stack exchange,提问作者Danny

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 14:30:01