Long story short, something's going on with Django migrations and user models that I don't understand. Something about foreign key relations with a customer user auth model and migrations is borked.
I developed the app localy with SQLite, and a custom user object: class Client(AbstractBaseUser, PermissionsMixin)
In my settings.py, I have:
AUTH_USER_MODEL = "offerdrive.Client"
Everything's worked with SQLite and local/development, and the app has a reasonable featureset at this point.
When time came to move to production, I tried Postgres, and it failed. Then I tried MySQL on RDS, and it failed the same way.
Here's the MySql error after a ./manage.py migrate
:
django.db.utils.IntegrityError: (1215, 'Cannot add foreign key constraint')
Here's some InnoDB debugging information for the curious (from mysql> show engine innodb status\G
) -
------------------------
LATEST FOREIGN KEY ERROR
------------------------
2015-08-05 22:01:36 2af53b3cf700 Error in foreign key constraint of table test_drivedb/#sql-a69_248:
FOREIGN KEY (`user_id`) REFERENCES `offerdrive_client` (`id`):
Cannot resolve table name close to:
(`id`)
I "flattened" all of my migrations the "old-fashioned" way to be sure - rm -rf'ed
the migrations
directory, and redid makemigrations
.
Some stuff I've read, and tried, which has failed to fully rectify the issue:
[1] Django 1.8 RC1: ProgrammingError when creating database tables.
[2] https://code.djangoproject.com/ticket/24524
Tests still fail the same way, unfortunately - even if the normal/prod database is migrated properly, and the migrations work consistently, the test database stuffs fail with the same foreign key issue.
I can get the actual database working fine if I'm careful about the order in which I migrate:
./manage.py reset_db
./manage.py migrate auth
./manage.py offerdrive
./manage migrate
But, this doesn't seem to hold for tests- it doesn't seem like running ./manage.py test offerdrive
enforces the order in any way. It fails the same way - complaining about the same foreign key relations.
This seems like an absolutely silly issue for a framework like Django, and I'm thinking I'm doing something Really Silly. The app itself doesn't do anything weird or crazy. It's still baffling to me why it worked fine with SQLite but not Postgres or MySQL. My best guess is that SQLite is less strict with foreign key constraints somehow, and that even if the tables are created out of order, they will eventually resolve themselves. That, or something else. Possibly.
tl;dr computers are hard
Any thoughts?
Update - Apparently running migrate
twice in a row will work for the 'real' database - but this doesn't help for tests, which fail.