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在一个文件的头部插入数据的实例
May 02 Python
利用Python读取txt文档的方法讲解
Jun 23 Python
基于Python开发chrome插件的方法分析
Jul 07 Python
django用户登录和注销的实现方法
Jul 16 Python
Python面向对象之类和对象实例详解
Dec 10 Python
浅析python的Lambda表达式
Feb 27 Python
Python实现京东秒杀功能代码
May 16 Python
python读取大文件越来越慢的原因与解决
Aug 08 Python
Python实现密钥密码(加解密)实例详解
Apr 26 Python
python如何支持并发方法详解
Jul 25 Python
python时间序列数据转为timestamp格式的方法
Aug 03 Python
Python爬虫获取op.gg英雄联盟英雄对位胜率的源码
Jan 29 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
PHP4中实现动态代理
2006/10/09 PHP
PHP实现多服务器session共享之NFS共享的方法
2007/03/16 PHP
php disk_free_space 返回目录可用空间
2010/05/10 PHP
PHP校验ISBN码的函数代码
2011/01/17 PHP
Smarty使用自定义资源的方法
2015/08/08 PHP
jQuery源码分析之Event事件分析
2010/06/07 Javascript
javascript Window及document对象详细整理
2011/01/12 Javascript
使用jquery的ajax需要注意的地方dataType的设置
2013/08/12 Javascript
js控制frameSet示例
2013/09/10 Javascript
14款NodeJS Web框架推荐
2014/07/11 NodeJs
js实现滑动触屏事件监听的方法
2015/05/05 Javascript
jquery实现顶部向右伸缩的导航区域代码
2015/09/02 Javascript
jQuery进行组件开发完整实例
2015/12/15 Javascript
文本框只能输入数字的js代码(含小数点)
2016/07/10 Javascript
用file标签实现多图文件上传预览
2017/02/14 Javascript
Vue.js中兄弟组件之间互相传值实例
2017/06/01 Javascript
使用Vue-Router 2实现路由功能实例详解
2017/11/14 Javascript
在angularJs中进行数据遍历的2种方法
2018/10/08 Javascript
swiper4实现移动端导航切换
2020/10/16 Javascript
手写Vue弹窗Modal的实现代码
2019/09/11 Javascript
在react中使用vue的状态管理的方法示例
2020/05/02 Javascript
原生JS运动实现轮播图
2021/01/02 Javascript
[01:07:11]Secret vs Newbee 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Python实现调度算法代码详解
2017/12/01 Python
Python实现的将文件每一列写入列表功能示例【测试可用】
2018/03/19 Python
Python 多维List创建的问题小结
2019/01/18 Python
基于Python的Post请求数据爬取的方法详解
2019/06/14 Python
numpy中三维数组中加入元素后的位置详解
2019/11/28 Python
python 爬取古诗文存入mysql数据库的方法
2020/01/08 Python
python GUI库图形界面开发之PyQt5计数器控件QSpinBox详细使用方法与实例
2020/02/28 Python
PyTorch预训练Bert模型的示例
2020/11/17 Python
Schecker荷兰:狗狗用品和配件
2019/06/06 全球购物
某公司.Net方向面试题
2014/04/24 面试题
外贸销售员求职的自我评价
2013/11/23 职场文书
数学检讨书1000字
2014/02/24 职场文书
2014年工程部工作总结
2014/11/25 职场文书