[Django] 解决 django.db.utils.OperationalError: 3780

因为我的 devel env 跟实际 production env 有太多的不同,所以我实际 deploy 的时候经常会出现一堆奇怪的问题。这边会尝试不定期记录下来我找到的各种暴力解法。


其中最近困扰我的就是这个:
django.db.utils.OperationalError: 3780 Referencing column and referenced column are incompatible

这个主因其实是我 devel 跟 production 的 Django 版本不一样,当然有很多因素让我选择不同步(因为连作业系统都不一样了),而这是一个很常见的 Error.

这个常见的因素是使用 ForeignKey 的时候, primary_key 有的版本或作业系统使用 BigAutoField 而有些使用 AutoField ,而在某些 DB 版本中,这两个会在 create table 时分别实作为 bigint 跟 int,而这个就是产生这个 Error 的主因。

ForeignKey 在实际使用时(假设叫做 xxx),会在 table 内建立一个 xxx_id ,而这个会去参照 ForeignKey 参照的 model 的 primary_key 。而如果两边的 Django 版本不同的话就很容易 raise 3780 出来。

解法其实很简单,首先找出出错的 migrations ,执行

python3 manage.py sqlmigrate <APP Name> <migration>

这个时候会出现一堆 SQL 指令,然后再执行

python3 manage.py dbshell

开始执行 sqlmigrate 得到的指令看是哪一行出错,找出出错的一行去 alter 成正确的就行了。
例如说假如 xxx 的 id 是 int auto_increment not null ,但是 ForeignKey 产生出来的 xxx_id 却是 bigint default null 的时候,那就执行:

alter table <table_name> modify column xxx_id int Default NULL;

就可以了。

然后如果出错的栏位后面还有其他 SQL commands 记得执行完。
最后因为其实已经在 database level 执行完了,所以可以直接把这个有问题的 migration fake 掉。

python3 manage.py sqlmigrate <APP Name> <migration> --fake

好了,暴力解完。虽然没有解决根本问题但是至少可以不用被这个问题挡住开发。


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章