Django 1.8 迁移、自定义用户模型和 Postgres/MySQL 的奇怪问题

Bizarre issues with Django 1.8 migrations, custom user model, and Postgres/MySQL

长话短说,Django 迁移和用户模型发生了一些我不理解的事情。关于与客户用户身份验证模型和迁移的外键关系的一些问题很无聊。

我使用 SQLite 和自定义用户对象在本地开发了应用程序:class Client(AbstractBaseUser, PermissionsMixin) 在我的 settings.py 中,我有:

AUTH_USER_MODEL = "offerdrive.Client"

一切都与 SQLite 和 local/development 一起工作,此时该应用程序具有合理的功能集。

当需要投入生产时,我尝试了 Postgres,但失败了。然后我在 RDS 上尝试了 MySQL,但同样失败了。 这是 ./manage.py migrate:

之后的 MySql 错误

django.db.utils.IntegrityError: (1215, 'Cannot add foreign key constraint')

这里有一些 InnoDB 调试信息供好奇(来自 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`)

我 "flattened" 我所有的迁移都是 "old-fashioned" 确定的方式 - rm -rf'ed migrations 目录,并重做 makemigrations.

我阅读并尝试过的一些内容未能完全解决问题:

[1] .

[2] https://code.djangoproject.com/ticket/24524

不幸的是,测试仍然以同样的方式失败 - 即使 normal/prod 数据库已正确迁移,并且迁移始终如一地工作,测试数据库的内容也会因相同的外键问题而失败。

如果我注意迁移的顺序,我可以让实际的数据库正常工作:

./manage.py reset_db
./manage.py migrate auth
./manage.py offerdrive
./manage migrate

但是,这似乎不适用于测试 - 运行 ./manage.py test offerdrive 似乎没有以任何方式强制执行该命令。它以同样的方式失败 - 抱怨相同的外键关系。

对于像 Django 这样的框架来说,这似乎是一个绝对愚蠢的问题,我认为我正在做一些非常愚蠢的事情。该应用程序本身不会做任何奇怪或疯狂的事情。我仍然感到困惑,为什么它在 SQLite 上运行良好但在 Postgres 或 MySQL 上运行良好。我最好的猜测是 SQLite 在某种程度上对外键约束不那么严格,即使表是乱序创建的,它们最终也会自行解决。那个,或者别的什么。有可能。

tl;dr 计算机很硬

有什么想法吗?

更新 - 显然 运行 migrate 连续两次将适用于 'real' 数据库 - 但这对失败的测试没有帮助。

哎哟小子。因此,经过一番努力,与其他人通信,再加上一点运气,最好的解决方案原来很简单——我需要 pip install --upgrade django-registration-redux .

1) 转折点是(我不敢相信我没有早点想到这一点)在 ./manage.py migrate -v3 上启用额外的详细信息并查看失败的确切位置(之前,我尝试删除调试器通过实际的 django 迁移加载/执行代码,事实证明这是错误的抽象级别)

2) 查看详细的迁移输出,很明显 registration_profile 表周围发生了爆炸。 (这是迁移失败前的最后一件事 运行)。

3) 我在应用程序对应的包 (django-registration / django-registration-redux) 周围进行了挖掘......aaaand,看起来没有迁移。这是一个问题,因为 Be aware, however, that unmigrated apps cannot depend on migrated apps, by the very nature of not having migrations. 根据“https://docs.djangoproject.com/en/1.8/topics/migrations/#dependencies

4) 一时兴起,在尝试将我自己的迁移添加到模块之前,我将 django-registration-reduxdjango-registration 升级为 pip install --upgrade

啊啊啊,它修好了。万岁#engineering!

我想指出这与自定义用户模块无关,只是一个我什至不知道的过时依赖项正在进入画面。

在尝试各种方法解决问题后,我终于从我的系统中完全删除了mysql(如果您有重要的数据库,请先备份)并重新安装。

然后我重复了通常的步骤:-

$./manage.py makemigrations
$./manage.py migrate

它奏效了。请记住,先迁移 "auth",然后再迁移其他应用。