iT邦幫忙

0

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

  • 分享至 

  • xImage
  •  

因為我的 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

好了,暴力解完。雖然沒有解決根本問題但是至少可以不用被這個問題擋住開發。


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言