django model去掉unique_together報(bào)錯(cuò)的解決方案
事情是這樣的,我有一個(gè)存儲(chǔ)考試的表
class Exam(models.Model):
category = cached_fields.ForeignKeyField(Category)
name = models.CharField(max_length=128)
date = models.DateField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
unique_together = ('category', 'date')
category 表示考試的類型, date 表示考試的日期。建表的時(shí)候考慮到一個(gè)類型的考試在同一個(gè)應(yīng)該只有一個(gè)考試,所以就加了一個(gè) unique_together 。但是由于業(yè)務(wù)需要,這個(gè) unique_together 不需要了。
用過 django 的人都知道,這不是個(gè)大問題,刪掉 unique_together 的代碼,然后 makemigrations 唄,確實(shí),我就這么做了。但是當(dāng)我 migrate 的時(shí)候卻報(bào)錯(cuò)了,錯(cuò)誤如下:
數(shù)據(jù)庫不讓我刪除這個(gè) index ,并且告訴我有一個(gè) 外鍵約束 用到了這個(gè)它。我就奇怪了,category是外鍵沒錯(cuò),但是我這個(gè)是 unique_together 啊,怎么可能有哪個(gè)外鍵用到了它呢?
沒辦法,我只能到數(shù)據(jù)庫里尋找答案, show create table exam ,輸出如下:
| insurance_exam | CREATE TABLE `insurance_exam` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(128) NOT NULL, `date` date NOT NULL, `created_at` datetime(6) NOT NULL, `updated_at` datetime(6) NOT NULL, `category_id` int(11) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `insurance_exam_category_id_a430e581_uniq` (`category_id`,`date`), CONSTRAINT `insurance_exam_category_id_a2238260_fk_insurance_category_id` FOREIGN KEY (`category_id`) REFERENCES `insurance_category` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1062 DEFAULT CHARSET=utf8mb4 |
可以看到 UNIQUE KEY 那一行就是 unique_together ,下面一行是 category 外鍵。沒有其他東西了啊,到底哪個(gè)外鍵用到了我們的 unique_together ?
外鍵只能是 category 了,也沒有別的外鍵啊。到底是怎么回事呢?
原因是這樣的: 在Mysql中外鍵會(huì)自動(dòng)在表上添加一個(gè)index ,也就說如果沒有unique_together,我們的表應(yīng)該是這樣的:
| insurance_exam | CREATE TABLE `insurance_exam` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(128) NOT NULL, `date` date NOT NULL, `created_at` datetime(6) NOT NULL, `updated_at` datetime(6) NOT NULL, `category_id` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `category_id` (`category_id`), CONSTRAINT `insurance_exam_category_id_a2238260_fk_insurance_category_id` FOREIGN KEY (`category_id`) REFERENCES `insurance_category` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1062 DEFAULT CHARSET=utf8mb4 |
但是因?yàn)橛辛?unique_together 的 unique_key ,并且 category 在聯(lián)合索引的左邊,根據(jù) 最左前綴 原則, category 的索引就有了,所以就不會(huì)另外建索引,這個(gè)時(shí)候 category 的外鍵約束就依賴了這個(gè) unique_key ,所以刪除的時(shí)候會(huì)出現(xiàn)那樣的報(bào)錯(cuò)。
機(jī)智的小伙伴應(yīng)該想到了,如果我們要去掉 unique_together ,我們可以將 category 的 KEY 加回去,這樣就可以將 unique_together 刪掉了。 sql 如下:
alter table exam add index(category_id);
這樣,migrate就能成功了。
- 解決django migrate報(bào)錯(cuò)ORA-02000: missing ALWAYS keyword
- Django 解決阿里云部署同步數(shù)據(jù)庫報(bào)錯(cuò)的問題
- Django-migrate報(bào)錯(cuò)問題解決方案
- 基于Django實(shí)現(xiàn)日志記錄報(bào)錯(cuò)信息
- 解決django model修改添加字段報(bào)錯(cuò)的問題
- Django之創(chuàng)建引擎索引報(bào)錯(cuò)及解決詳解
- Django重裝mysql后啟動(dòng)報(bào)錯(cuò):No module named ‘MySQLdb’的解決方法
- django啟動(dòng)uwsgi報(bào)錯(cuò)的解決方法
- django項(xiàng)目運(yùn)行因中文而亂碼報(bào)錯(cuò)的幾種情況解決
- Django如何實(shí)現(xiàn)密碼錯(cuò)誤報(bào)錯(cuò)提醒
相關(guān)文章
Flask表單與表單驗(yàn)證實(shí)現(xiàn)流程介紹
這篇文章主要介紹了python中Flask?Web?表單的使用方法介紹,表單的操作是Web程序開發(fā)中最核心的模塊之一,絕大多數(shù)的動(dòng)態(tài)交互功能都是通過表單的形式實(shí)現(xiàn)的。更多介紹需要的小伙伴可以參考下面文章內(nèi)容2022-09-09
Python語言實(shí)現(xiàn)百度語音識(shí)別API的使用實(shí)例
這篇文章主要介紹了Python語言實(shí)現(xiàn)百度語音識(shí)別API的使用實(shí)例,具有一定借鑒價(jià)值,需要的朋友可以參考下。2017-12-12
二種python發(fā)送郵件實(shí)例講解(python發(fā)郵件附件可以使用email模塊實(shí)現(xiàn))
這篇文章主要介紹了使用Python email模塊、smtplib庫發(fā)送郵件的實(shí)例,大家參考使用2013-12-12
PyTorch實(shí)現(xiàn)多維度特征輸入邏輯回歸
這篇文章主要介紹了PyTorch實(shí)現(xiàn)多維度特征輸入邏輯回歸,首先進(jìn)行數(shù)據(jù)采取數(shù)據(jù)集展開詳細(xì)內(nèi)容,需要的小伙伴可以參考一下2022-03-03
詳解Python中__new__和__init__的區(qū)別與聯(lián)系
在Python中,每個(gè)對(duì)象都有兩個(gè)特殊的方法:__new__和__init__,本文將詳細(xì)介紹這兩個(gè)方法的不同之處以及它們之間的聯(lián)系,具有一定的參考價(jià)值,感興趣的可以了解一下2023-12-12

