在现有数据库表中添加具有现有值的新Unique字段 - Django1.7 / MySql

时间:2016-10-16 14:16:10

标签: python mysql django

我有一个现有的数据库表。 我想为它添加一个新的(Char)字段。该字段将具有唯一值。

当我尝试这样做时:

id = models.CharField(max_length=100, Unique=True)

我得到完整性错误。

我尝试过的其他一些事情:

id = models.CharField(max_length=100, Unique=True,
default="".join([random.random(), random.random()])))

id = models.CharField(max_length=100,
default="".join([random.random(), random.random()])))

同样的错误。

有解决方法吗?

1 个答案:

答案 0 :(得分:2)

我将显示以下内容,新列是INT而不是CHAR。相同的区别。

create table t1
(   id int auto_increment primary key,
    col1 varchar(100) not null
);

insert t1(col1) values ('fish'),('apple'),('frog');
alter table t1 add column col2 int; -- OK (all of col2 is now NULL)
ALTER TABLE t1 ADD UNIQUE (col2); -- OK (now a UNIQUE constraint on col2)

show create table t1;
CREATE TABLE `t1` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `col1` varchar(100) NOT NULL,
   `col2` int(11) DEFAULT NULL,
   PRIMARY KEY (`id`),
   UNIQUE KEY `col2` (`col2`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

现在让我们重新开始,看看它爆炸了。

drop table t1;
create table t1
(   id int auto_increment primary key,
    col1 varchar(100) not null
);
insert t1(col1) values ('fish'),('apple'),('frog');
alter table t1 add column col2 int not null; -- OK (at the moment)
-- note: (all of col2 is now 0)
ALTER TABLE t1 ADD UNIQUE (col2); -- error 1062 duplicate entry '0' for key 'col2'

上述爆炸的原因是因为col2 add列上的NOT NULL使所有数据都为0.然后UNIQUE约束尝试失败。

现在让我们继续思考:

drop table t1;
create table t1
(   id int auto_increment primary key,
    col1 varchar(100) not null
);
insert t1(col1) values ('fish'),('apple'),('frog');
alter table t1 add column col2 int; -- OK (all of col2 is now NULL)
ALTER TABLE t1 ADD UNIQUE (col2); -- OK
select * from t1; -- col2 is NULL for all 3 rows
update t1 set col2=7 where id=1; -- OK
update t1 set col2=7 where id=2; -- error 1062 duplicate entry '7' for key 'col2'

故事的寓意是,如果您将一个列添加到预先存在数据的表中,并希望该新列是唯一的,那么您需要让它可以启动。然后创建唯一约束。现在所有数据都是NULL,因此唯一约束是宽容的。但是一旦你将数据调整为非NULL,它最好是唯一的。 Tweak意思是UPDATE或INSERT。因此col2需要保持NULL或UNIQUE。