[英]Django “relation does not exist” error with custom user class and Postgresql schemas
I am getting a django.db.utils.ProgrammingError: relation "user" does not exist
error when running createsuperuser
on a Django project with a Postgresql database. 我收到
django.db.utils.ProgrammingError: relation "user" does not exist
在具有Postgresql数据库的Django项目上运行createsuperuser
时, django.db.utils.ProgrammingError: relation "user" does not exist
错误。
I wrote the following database router to indicate that the table user
(which is based on a custom extension of the AbstractUser
class) is in the schema users
. 我编写了以下数据库路由器,以指示表
user
(基于AbstractUser
类的自定义扩展名)在架构users
。 Even so, Django cannot find it. 即使这样,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
The router works for other tables unrelated to authentication, so I suspect this has to do with the other tables automatically created by Django when I migrated the User class for the first time ( auth_group
, auth_group_permissions
, auth_permission
, django_admin_log
, django_content_type
, django_session
). 路由器可用于与身份验证无关的其他表,因此我怀疑这与Django首次迁移User类时自动创建的其他表有关(
auth_group
, auth_group_permissions
, auth_permission
, django_admin_log
, django_content_type
, django_session
)。
However, I'm not sure: 但是,我不确定:
if
/ elif
) --> is there a better way to write a router for more than one schema? if
/ elif
)->是否有更好的方法为多个模式编写路由器? django_admin_log
, django_content_type
, django_session
) by looking into django/contrib
directories, but how am I supposed to find those for auth_group
, auth_group_permissions
, auth_permission
? django/contrib
目录,我能够猜出最后三个类名( django_admin_log
, django_content_type
, django_session
),但是我应该如何找到auth_group
, auth_group_permissions
, auth_permission
那些呢? EDIT: based on the comment from @Kevin, I tried writing the routers based on app_label
s rather than model names, as shown in the docs, making one router for each app involved. 编辑:基于@Kevin的评论,我尝试根据
app_label
而不是型号名称编写路由器,如文档所示,为涉及的每个应用程序制作一个路由器。 I also tried manually specifying the app_label
in the Meta class of my User class (ie app_label = 'users'
). 我还尝试在User类的Meta类中手动指定
app_label
(即app_label = 'users'
)。
However the original error ( django.db.utils.ProgrammingError: relation "user" does not exist
) persists when I enter a username in createsuperuser
. 但是,当我在
createsuperuser
输入用户名时,原始错误( django.db.utils.ProgrammingError: relation "user" does not exist
)仍然存在。 How else am I supposed to handle this situation in the router? 我还应该如何处理路由器中的这种情况?
#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
Then, I call them from settings.py
in the following order: 然后,我按以下顺序从
settings.py
调用它们:
DATABASE_ROUTERS = (
'urbio.dbrouters.AdminRouter',
'urbio.dbrouters.AuthRouter',
'urbio.dbrouters.ContentTypeRouter',
'urbio.dbrouters.SessionRouter',
'urbio.dbrouters.UsersRouter',
)
The solution was to specify the --database
flag and point to the correct schema when running the createsuperuser
command: 解决方案是在运行
createsuperuser
命令时指定--database
标志并指向正确的架构:
python manage.py createsuperuser --database users
Also, following this answer , the database definition in settings.py
is: 另外,遵循此答案 ,
settings.py
的数据库定义为:
DATABASES = {
'default':
{},
'schema1':
{
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'OPTIONS': {
'options': '-c search_path=schema1'
},
'NAME': 'mydbname',
'USER': 'myusername',
'PASSWORD': '***',
'HOST': 'my.host.address',
'PORT': '5432',
},
'users':
{
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'OPTIONS': {
'options': '-c search_path=users'
},
'NAME': 'mydbname',
'USER': 'myusername',
'PASSWORD': '***',
'HOST': 'my.host.address',
'PORT': '5432',
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.