PhoneGap中文网

 找回密码
 立即注册
查看: 17244|回复: 0
打印 上一主题 下一主题

Django model去掉unique_together报错

[复制链接]

87

主题

87

帖子

327

积分

中级会员

Rank: 3Rank: 3

积分
327
跳转到指定楼层
楼主
发表于 2017-8-12 14:24:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本文和大家分享的主要是Django model去掉unique_together报错问题相关解决办法,一起来看看吧,希望对大家学习django有所帮助。
  事情是这样的,我有一个存储考试的表
  class Exam(models.Model):
  category = models.ForiegnKey(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就能成功了。
来源: youmai の Blog
it营
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

ionic4视频教程

Archiver|手机版|小黑屋| PhoneGap中文网 ( 京ICP备13027796号-1 )  

GMT+8, 2024-12-22 16:24 , Processed in 0.080277 second(s), 28 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表