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

Posted

技术标签:

【中文标题】Django 1.8 迁移、自定义用户模型和 Postgres/MySQL 的奇怪问题【英文标题】:Bizarre issues with Django 1.8 migrations, custom user model, and Postgres/MySQL 【发布时间】:2015-10-28 21:51:18 【问题描述】:

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

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

AUTH_USER_MODEL = "offerdrive.Client"

一切都与 SQLite 和本地/开发一起工作,并且该应用程序此时具有合理的功能集。

到了生产环境的时候,我尝试了 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`)

我以“老式”方式“扁平化”了我的所有迁移,以确保 - rm -rf'ed migrations 目录,并重做 makemigrations

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

[1]Django 1.8 RC1: ProgrammingError when creating database tables.

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

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

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

./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 将适用于“真实”数据库 - 但这对失败的测试没有帮助。

【问题讨论】:

【参考方案1】:

嘿男孩。因此,经过一番辛勤工作、与其他人的一些通信以及一点运气,结果证明最好的解决方案很简单——我需要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

Aaa 并且它修复了它。万岁#engineering!

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

【讨论】:

【参考方案2】:

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

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

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

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

【讨论】:

以上是关于Django 1.8 迁移、自定义用户模型和 Postgres/MySQL 的奇怪问题的主要内容,如果未能解决你的问题,请参考以下文章

从 django 用户模型迁移到自定义用户模型

将旧 (Django 0.97) 模型数据导入/迁移到 Django 1.8 或更高版本

如何将自定义用户模型迁移到 Django 中的不同应用程序?

将现有 auth.User 数据迁移到新的 Django 1.5 自定义用户模型?

django 1.8 测试模型和迁移

Django 管理员无法使用自定义用户模型正确登录