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 subprocess模块学习总结
Mar 13 Python
python中MySQLdb模块用法实例
Nov 10 Python
python统计一个文本中重复行数的方法
Nov 19 Python
python实现矩阵乘法的方法
Jun 28 Python
解决Scrapy安装错误:Microsoft Visual C++ 14.0 is required...
Oct 01 Python
详解使用 pyenv 管理多个版本 python 环境
Oct 19 Python
微信跳一跳游戏python脚本
Apr 01 Python
Python判断两个文件是否相同与两个文本进行相同项筛选的方法
Mar 01 Python
python发送多人邮件没有展示收件人问题的解决方法
Jun 21 Python
numpy ndarray 按条件筛选数组,关联筛选的例子
Nov 26 Python
详解Python描述符的工作原理
Jun 11 Python
python机器学习Github已达8.9Kstars模型解释器LIME
Nov 23 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
php 获取mysql数据库信息代码
2009/03/12 PHP
php插入含有特殊符号数据的处理方法
2016/11/24 PHP
PHP使用PDO 连接与连接管理操作实例分析
2020/04/21 PHP
Javascript(AJAX)解析XML的代码(兼容FIREFOX/IE)
2010/07/11 Javascript
css值转换成数值请抛弃parseInt
2011/10/24 Javascript
jquery select多选框的左右移动 具体实现代码
2013/07/03 Javascript
Jquery显示和隐藏元素或设为只读(含Ligerui的控件禁用,实例说明介绍)
2013/07/09 Javascript
jsPDF导出pdf示例
2014/05/02 Javascript
JS中getYear()和getFullYear()区别分析
2014/07/04 Javascript
JavaScript实现将文本框的值插入指定位置的方法
2015/08/13 Javascript
javascript使用Promise对象实现异步编程
2016/03/01 Javascript
PHP实现本地图片上传和验证功能
2017/02/27 Javascript
Vue.js实现价格计算器功能
2020/03/30 Javascript
Three.js如何用轨迹球插件(trackball)增加对模型的交互功能详解
2017/09/25 Javascript
vue中mint-ui的使用方法
2018/04/04 Javascript
讲解vue-router之命名路由和命名视图
2018/05/28 Javascript
Nuxt.js SSR与权限验证的实现
2018/11/21 Javascript
[原创]微信小程序获取网络类型的方法示例
2019/03/01 Javascript
构建Vue大型应用的10个最佳实践(小结)
2019/11/07 Javascript
JavaScript实现留言板案例
2020/03/17 Javascript
JavaScript实现移动端弹窗后禁止滚动
2020/05/25 Javascript
[02:32]DOTA2英雄基础教程 祸乱之源
2013/12/23 DOTA
Python 列表(List)操作方法详解
2014/03/11 Python
python好玩的项目—色情图片识别代码分享
2017/11/07 Python
python实现微信跳一跳辅助工具步骤详解
2018/01/04 Python
python 获取当天每个准点时间戳的实例
2018/05/22 Python
django 中QuerySet特性功能详解
2019/07/25 Python
对Django url的几种使用方式详解
2019/08/06 Python
用html5实现语音搜索框的方法
2014/03/18 HTML / CSS
德国高性价比网上药店:medpex
2017/07/09 全球购物
校长就职演讲稿
2014/01/06 职场文书
毕业实习评语
2014/02/10 职场文书
教师开学感言
2014/02/14 职场文书
港澳通行证委托书怎么写
2014/08/02 职场文书
建国70周年的心得体会(2篇)
2019/09/20 职场文书
JS封装cavans多种滤镜组件
2022/02/15 Javascript