在具有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_group
,auth_group_permissions
)时自动创建的其他表有关。 ,auth_permission
,django_admin_log
,django_content_type
,django_session
)。
但是,我不确定:
if
/ elif
)->是否有更好的方法为多个模式编写路由器?django_admin_log
目录,我能够猜出最后三个类的名称(django_content_type
,django_session
,django/contrib
),但是我应该如何找到它们呢?用于auth_group
,auth_group_permissions
,auth_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',
)