Opened 6 years ago

Closed 6 years ago

Last modified 2 years ago

#29564 closed Bug (invalid)

Executing createsuperuser with non-default database.

Reported by: Oleg Żero Owned by: nobody
Component: contrib.auth Version: 2.0
Severity: Normal Keywords: multiple database router createsuperuser
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Oleg Żero)

Hello!

I tried to use a different, non-default designated database for storing (auth, admin, contenttype, session), named 'users', another one for that is application-specific 'application' and 'default' is then used for everything else, like this:

...
DATABASES = {
    'default':  dj_database_url.parse(os.environ['DATABASE_OPS_URL'], conn_max_age=500), # for everything else...
    'users':     dj_database_url.parse(os.environ['DATABASE_USR_URL'], conn_max_age=500), # for auth-stuff
    'application': dj_database_url.parse(os.environ['DATABSE_APP_URL'], conn_max_age=500), # for app
}
DATABASE_ROUTERS = ['myapplication.routers.AuthRouter']
...

Following your example https://docs.djangoproject.com/en/2.0/topics/db/multi-db/#topics-db-multi-db-routing,
I created a router.py, in which I replicated your code.
However, being aware of the cross-database problem, my routers.py looks like this:

class AuthRouter(object):
    auth_related = (
            'auth',
            'admin',
            'contenttypes',
            'sessions',
    )

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

    def db_for_write(self, model, **hints):
        if model._meta.app_label in self.auth_related:
            return 'users'
        return None

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

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

Then:

$ ./manage.py migrate
$ ./manage.py migrate --database=users
$ ./manage.py migrate --database=application

Works fine. I verified the database content, and yes, the tables are created in 'users'.

However, when executing:

$ ./manage.py createsuperuser

I get prompted to define the name, but just after I hit enter, I get a django.db.utils.ProgrammingError: relation "auth_user" does not exist
LINE 1: ...user"."is_active", "auth_user"."date_joined" FROM "auth_user...

...and django fails to initialize that user.
The only way I can get it to work, is when the 'users' database matches the 'default' one.
How do I work around it? Is it a bug?

Thank you very much in advance!

Change History (4)

comment:1 by Oleg Żero, 6 years ago

Description: modified (diff)

comment:2 by Tim Graham, 6 years ago

Component: Migrationscontrib.auth
Resolution: invalid
Status: newclosed
Type: UncategorizedBug

createsuperuser takes a --database option just like migrate. In the future, please see TicketClosingReasons/UseSupportChannels to find places to get help until you confirm a bug.

comment:3 by David A, 2 years ago

I know I'm going to upset someone for posting on a 4yr old topic. but this is more a documentation bug, but I've long since learned that django docs are lacking...

comment:4 by Tim Graham, 2 years ago

What's the bug? createsuperuser --database is documented.

Note: See TracTickets for help on using tickets.
Back to Top