Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom user models and South

I'm trying to use a custom user model in the most basic way, extending AbstractUser as described at Extending Django’s default User. But, I'm not sure how to properly make this work with South. I'm running into a problem when doing an initial schema migration with Here's what happening:

  • I've got my extended user class, Player, in my class tournaments, which is enabled in settings.INSTALLED_APPS.

  • To perform an initial syncdb, the tournaments app must be enabled. Otherwise I get this error:

    $ ./manage.py syncdb
    CommandError: One or more models did not validate:
    auth.user: Model has been swapped out for 'tournaments.Player' which has not been installed or is abstract.
    admin.logentry: 'user' has a relation with model tournaments.Player, which has either not been installed or is abstract.
    
  • So, I enable the tournaments app that has my Player (custom user) model. But then, upon the initial migration:

    $ ./manage.py schemamigration tournaments --initial 
    ...
    $ ./manage.py migrate tournaments
    Running migrations for tournaments:
     - Migrating forwards to 0001_initial.
     > tournaments:0001_initial
    FATAL ERROR - The following SQL query failed: CREATE TABLE "tournaments_player" ("id" serial NOT NULL PRIMARY KEY, "password" varchar(128) NOT NULL, "last_login" timestamp with time zone NOT NULL, "is_superuser" boolean NOT NULL, "username" varchar(30) NOT NULL UNIQUE, "first_name" varchar(30) NOT NULL, "last_name" varchar(30) NOT NULL, "email" varchar(75) NOT NULL, "is_staff" boolean NOT NULL, "is_active" boolean NOT NULL, "date_joined" timestamp with time zone NOT NULL, "bio" text NOT NULL);
    The error was: relation "tournaments_player" already exists
    
    Error in migration: tournaments:0001_initial
    DatabaseError: relation "tournaments_player" already exists
    

If I skip the syncdb, I get this error, because syncdb is necessary to bootstrap South:

$ ./manage.py migrate tournaments
DatabaseError: relation "south_migrationhistory" does not exist
LINE 1: ...gration", "south_migrationhistory"."applied" FROM "south_mig...

So, it appears that I've got a chicken/egg situation here: I can't syncdb without my user model. But, if I syncdb with my user model, I can't perform an initial migration!

What is the best way to get around this? I've got some ideas, like running the initial syncdb without django.contrib.auth and django.contrib.admin enabled, or running the initial syncdb without south enabled and then converting the app. Both options seem hackey and strange.

like image 688
Dmitry Minkovsky Avatar asked Apr 08 '13 04:04

Dmitry Minkovsky


2 Answers

Try running ./manage.py migrate tournaments --fake 0001. This will add an entry into the south migration history saying that the initial migration has run, without actually executing the SQL. Alternatively, you can set class Meta: managed = False on the custom user object to tell django not to ever syncdb that model.

like image 172
Thomas Avatar answered Sep 28 '22 02:09

Thomas


This worked:

  • Comment django.contrib.auth, django.contrib.admin and tournament (the app with my custom user model in settings.INSTALLED_APPS.
  • manage.py syncdb
  • Uncomment django.contrib.auth, django.contrib.admin and tournament
  • manage.py schemamigration tournaments --initial
  • manage.py syncdb
  • manage.py migrate tournaments

Quite hackey and terrible. Would love to know a better way.

like image 35
Dmitry Minkovsky Avatar answered Sep 28 '22 02:09

Dmitry Minkovsky