自定义用户类和Postgresql模式的Django“不存在关系”错误

时间:2019-02-25 22:40:30

标签: python django postgresql database-schema

在具有Postgresql数据库的Django项目上运行django.db.utils.ProgrammingError: relation "user" does not exist时,出现createsuperuser错误。

我写了以下数据库路由器,以指示表user(基于AbstractUser类的自定义扩展名)在模式users中。即使这样,Django也找不到它。

from myapp.models import Class1, Class2, Class3
from users.models import User
from django.contrib.admin.models import LogEntry
from django.contrib.contenttypes.models import ContentType
from django.contrib.sessions.models import Session

# Include here classes (i.e. tables) that belongs to the "myapp" schema
ROUTED_MODELS_MYAPP = [Class1, Class2, Class3]

# Include here classes (i.e. tables) that belongs to the "users" schema
ROUTED_MODELS_USERS = [User, LogEntry, ContentType, Session] #classes for custom user model, and django tables `django_admin_log`, `django_content_type`, `django_session` tables
# classes for the following table names still missing from list: `auth_group`, `auth_group_permissions`, `auth_permission`.

class MyDBRouter(object):
    """
    A router to place DB queries into correct schema depending on considered tables.
    Sources: 
        https://stackoverflow.com/a/51007441/3976696
        https://www.amvtek.com/blog/posts/2014/Jun/13/accessing-multiple-postgres-schemas-from-django/
    """
    def db_for_read(self, model, **hints):
        if model in ROUTED_MODELS_MYAPP:
            return 'myapp'
        elif model in ROUTED_MODELS_USERS:
            return 'users'
        return None

    def db_for_write(self, model, **hints):
        if model in ROUTED_MODELS_MYAPP:
            return 'myapp'
        elif model in ROUTED_MODELS_USERS:
            return 'users'        
        return None   

路由器可用于与身份验证无关的其他表,因此我怀疑这与Django首次迁移User类(auth_groupauth_group_permissions)时自动创建的其他表有关。 ,auth_permissiondjango_admin_logdjango_content_typedjango_session)。

但是,我不确定:

  1. 如果应该像我那样写路由器(序列为 if / elif)->是否有更好的方法为多个模式编写路由器?
  2. 与之对应的型号名称 上面列出的Django表。 ->通过查看django_admin_log目录,我能够猜出最后三个类的名称(django_content_typedjango_sessiondjango/contrib),但是我应该如何找到它们呢?用于auth_groupauth_group_permissionsauth_permission

编辑:根据@Kevin的评论,我尝试根据app_label而不是型号名称(如文档中所示)编写路由器,为每个应用制作一个路由器参与。我还尝试在User类的Meta类(即app_label)中手动指定app_label = 'users'

但是,当我在django.db.utils.ProgrammingError: relation "user" does not exist中输入用户名时,原始错误(createsuperuser)仍然存在。我应该如何处理路由器中的这种情况?

#Route all models in admin application, cf. https://docs.djangoproject.com/en/2.1/topics/db/multi-db/
class AdminRouter:
    """
    A router to control all database operations on models in the admin application.
    """
    def db_for_read(self, model, **hints):
        """
        Attempts to read admin models go to users.
        """
        if model._meta.app_label == 'admin':
            return 'users'
        return None

    def db_for_write(self, model, **hints):
        """
        Attempts to write admin models go to users.
        """
        if model._meta.app_label == 'admin':
            return 'users'
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        """
        Make sure the admin app only appears in the 'users' database.
        """
        if app_label == 'admin':
            return db == 'users'
        return None

class AuthRouter:
    """
    A router to control all database operations on models in the
    auth application.
    """
    <similar to previous router>

class ContentTypeRouter:
    """
    A router to control all database operations on models in the
    contenttype application.
    """
    <similar to previous router>

class SessionRouter:
    """
    A router to control all database operations on models in the
    sessionapplication.
    """
    <similar to previous router>

#Route all models in users application, cf. https://docs.djangoproject.com/en/2.1/topics/db/multi-db/
class UsersRouter:
    """
    A router to control all database operations on models in the users application.
    """
    def db_for_read(self, model, **hints):
        """
        Attempts to read user models go to users.
        """
        if model._meta.app_label == 'users':
            return 'users'
        return None

    def db_for_write(self, model, **hints):
        """
        Attempts to write user models go to users.
        """
        if model._meta.app_label == 'users':
            return 'users'
        return None

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        """
        Make sure the user app only appears in the 'users' database.
        """
        if app_label == 'users':
            return db == 'users'
        return None

然后,我按以下顺序从settings.py进行呼叫:

DATABASE_ROUTERS = (
                    'urbio.dbrouters.AdminRouter',
                    'urbio.dbrouters.AuthRouter', 
                    'urbio.dbrouters.ContentTypeRouter', 
                    'urbio.dbrouters.SessionRouter', 
                    'urbio.dbrouters.UsersRouter',
                    )

0 个答案:

没有答案