【发布时间】:2019-07-19 10:08:57
【问题描述】:
在使用 Postgresql 数据库的 Django 项目上运行 createsuperuser 时出现django.db.utils.ProgrammingError: relation "user" does not exist 错误。
我编写了以下数据库路由器来指示表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
路由器适用于与身份验证无关的其他表,所以我怀疑这与我第一次迁移 User 类时由 Django 自动创建的其他表有关(auth_group、auth_group_permissions、auth_permission , django_admin_log, django_content_type, django_session)。
但是,我不确定:
- 如果应该像我一样编写路由器(一系列
if/elif) --> 有没有更好的方法为多个模式编写路由器? - 哪些型号名称对应于
上面列出的 Django 表。 --> 通过查看
django/contrib目录,我能够猜出最后三个类名(django_admin_log、django_content_type、django_session),但我应该如何找到auth_group、auth_group_permissions的名称,auth_permission?
编辑:根据@Kevin 的评论,我尝试根据app_labels 而不是型号名称编写路由器,如文档中所示,为每个涉及的应用程序制作一个路由器。我还尝试在我的 User 类的 Meta 类中手动指定app_label(即app_label = 'users')。
但是,当我在 createsuperuser 中输入用户名时,原始错误 (django.db.utils.ProgrammingError: relation "user" does not exist) 仍然存在。我还应该如何处理路由器中的这种情况?
#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',
)
【问题讨论】:
-
与其列出模型,不如使用the documentation:
if model._meta.app_label == 'auth':中显示的方法似乎更容易。 -
@KevinChristopherHenry 感谢您的建议。我试过了(请参阅原始帖子中的编辑),但不幸的是它似乎无法正常工作。您还有其他想法吗?
标签: python django postgresql database-schema