django model去掉unique_together报错的解决方案


Posted in Python onOctober 18, 2016

事情是这样的,我有一个存储考试的表

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 表示考试的日期。建表的时候考虑到一个类型的考试在同一个应该只有一个考试,所以就加了一个 unique_together 。但是由于业务需要,这个 unique_together 不需要了。

用过 django 的人都知道,这不是个大问题,删掉 unique_together 的代码,然后 makemigrations 呗,确实,我就这么做了。但是当我 migrate 的时候却报错了,错误如下:

django.db.utils.OperationalError: (1553, "Cannot drop index 'insurance_exam_category_id_a430e581_uniq': needed in a foreign key constraint")

数据库不让我删除这个 index ,并且告诉我有一个 外键约束 用到了这个它。我就奇怪了,category是外键没错,但是我这个是 unique_together 啊,怎么可能有哪个外键用到了它呢?

没办法,我只能到数据库里寻找答案, 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 外键。没有其他东西了啊,到底哪个外键用到了我们的 unique_together

外键只能是 category 了,也没有别的外键啊。到底是怎么回事呢?

原因是这样的: 在Mysql中外键会自动在表上添加一个index ,也就说如果没有unique_together,我们的表应该是这样的:

| 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 |

但是因为有了 unique_together unique_key ,并且 category 在联合索引的左边,根据 最左前缀 原则, category 的索引就有了,所以就不会另外建索引,这个时候 category 的外键约束就依赖了这个 unique_key ,所以删除的时候会出现那样的报错。

机智的小伙伴应该想到了,如果我们要去掉 unique_together ,我们可以将 category KEY 加回去,这样就可以将 unique_together 删掉了。 sql 如下:

alter table exam add index(category_id);

这样,migrate就能成功了。

Python 相关文章推荐
python通过BF算法实现关键词匹配的方法
Mar 13 Python
Python进阶篇之字典操作总结
Nov 16 Python
Python3利用SMTP协议发送E-mail电子邮件的方法
Sep 30 Python
Pycharm2017版本设置启动时默认自动打开项目的方法
Oct 29 Python
浅析Python与Mongodb数据库之间的操作方法
Jul 01 Python
python-tornado的接口用swagger进行包装的实例
Aug 29 Python
Python实现CNN的多通道输入实例
Jan 17 Python
pyecharts绘制中国2020肺炎疫情地图的实例代码
Feb 12 Python
Python3操作YAML文件格式方法解析
Apr 10 Python
如何利用Python给自己的头像加一个小国旗(小月饼)
Oct 02 Python
python 实时调取摄像头的示例代码
Nov 25 Python
使用OpenCV校准鱼眼镜头的方法
Nov 26 Python
django批量导入xml数据
Oct 16 #Python
python中os模块详解
Oct 14 #Python
python append、extend与insert的区别
Oct 13 #Python
CentOS6.5设置Django开发环境
Oct 13 #Python
Python判断某个用户对某个文件的权限
Oct 13 #Python
python使用str & repr转换字符串
Oct 13 #Python
PYTHON 中使用 GLOBAL引发的一系列问题
Oct 12 #Python
You might like
论建造顺序的重要性
2020/03/04 星际争霸
使用php4加速网络传输
2006/10/09 PHP
PHP如何抛出异常处理错误
2011/03/02 PHP
PHP用strstr()函数阻止垃圾评论(通过判断a标记)
2013/09/28 PHP
PHP CURL获取cookies模拟登录的方法
2013/11/04 PHP
层序遍历在ExtJs的TreePanel中的应用
2009/10/16 Javascript
让浏览器非阻塞加载javascript的几种方法小结
2011/04/25 Javascript
JavaScript限定复选框的选择个数示例代码
2013/08/25 Javascript
JQuery伸缩导航练习示例
2013/11/13 Javascript
JS+CSS实现仿触屏手机拨号盘界面及功能模拟完整实例
2015/05/16 Javascript
深入理解JavaScript中Ajax
2016/08/02 Javascript
js倒计时显示实例
2016/12/11 Javascript
Vue2组件tree实现无限级树形菜单
2017/03/29 Javascript
微信小程序实现animation动画
2018/01/26 Javascript
解决vue js IOS H5focus无法自动弹出键盘的问题
2018/08/30 Javascript
在vue中多次调用同一个定义全局变量的实例
2018/09/25 Javascript
vue基于element-ui的三级CheckBox复选框功能的实现代码
2018/10/15 Javascript
JavaScript对象拷贝与赋值操作实例分析
2018/12/10 Javascript
vue实现form表单与table表格的数据关联功能示例
2019/01/29 Javascript
jQuery实现文本显示一段时间后隐藏的方法分析
2019/06/20 jQuery
详谈Vue.js框架下main.js,App.vue,page/index.vue之间的区别
2020/08/12 Javascript
OpenLayer学习之自定义测量控件
2020/09/28 Javascript
网红编程语言Python将纳入高考你怎么看?
2018/06/07 Python
Python时间序列处理之ARIMA模型的使用讲解
2019/04/02 Python
python实现按首字母分类查找功能
2019/10/31 Python
Django权限设置及验证方式
2020/05/13 Python
美国女鞋品牌:naturalizer(娜然)
2016/08/01 全球购物
Eclipse面试题
2014/03/22 面试题
Java里面有没有全局变量?为什么?
2015/02/06 面试题
25道Java面试题集合
2013/05/21 面试题
企业办公室岗位职责
2014/03/12 职场文书
财务务虚会发言材料
2014/10/20 职场文书
四十年同学聚会致辞
2015/07/28 职场文书
Python中的min及返回最小值索引的操作
2021/05/10 Python
分享一些Java的常用工具
2021/06/11 Java/Android
MySQL分区表实现按月份归类
2021/11/01 MySQL