1. 程式人生 > >禁用django的物理外來鍵(CONSTRAINT,REFERENCES)

禁用django的物理外來鍵(CONSTRAINT,REFERENCES)

背景

用django自帶的admin和auth搭建了內部網站,使用了django的使用者和許可權分組系統,但是在移到生產環境時發現公司把REFERENCES這種命令禁止了,DBA說影響效能不給開許可權,所以不得不嘗試把外來鍵從db層移到應用層。

第一次嘗試

於是模仿https://www.zhihu.com/question/61129892/answer/189472143中,對AbstractBaseUser和PermissionsMixin這兩個類裡只要用到ForeignKey或者manttomany的欄位都加上db_constraint=False這個引數。具體程式碼就不展示了。反正最後不是很順利,跟內部很多東西有衝突,看起來即使弄好了也沒法用許可權系統,因此嘗試其他方法。

第二次嘗試

思路:之後就把目光投向了django本身對於db的全域性設定,因為我在看文件時無意中看到關於InnoDB相關的東西,後來通過https://docs.djangoproject.com/en/2.0/ref/databases/#storage-engines得知,只有InnoDB支援物理外來鍵,而MyISAM不支援。也就是說如果我使用MyISAM的話,django可能就不得不把外來鍵放在物理層了。

於是參考文件在setting的DATABASES中default中添加了

'OPTIONS': {
             'init_command': 'SET default_storage_engine=MyISAM'
, },

這一引數,再次重新生成資料庫就發現沒有物理外來鍵了。

後記

雖然這樣設定了,但是在生產環境db上初始化時還是會出現django.db.utils.OperationalError: (1142, "REFERENCES command denied to user 'xxx'@'xxxx' for table 'django_content_type'")的報錯,但是把本地的db匯出sql語句時並沒有REFERENCES命令。於是就直接在本地資料庫初始化,之後生成見表語句後匯入生產db即可。

ps:最好把本地初始化時的資料和表結構一起匯入,不然的話’auth_permission’這個表會是空的,之後用admin介面的話管理員進去也沒有許可權。