Django中修改已有表的主键:删除表,新建表,迁移
在项目中已经迁移好的表,发现其中的主键尽然不是唯一的,于是只能另外设定一个。
对于一个现有主键的数据表而言,如果要更改或者添加另外的主键,可能最靠谱的方式就是删除后重新建表了。如果当前表中没有外键,或者当前表的主键没有被其他表引用为外键,那还比较清晰地分清楚哪些数据和这个表相关的,否则会更麻烦。
如果仅仅是在models中更改、添加新主键,那在重新迁移过程中,DJ那是各种报错。因为新添加的主键和现有表中的主键产生了冲突。DJ没有办法帮你决定是否要保留数据还是其他。要保留,DJ做不到,不保留,DJ不想承担删数据跑路的这个责任。所以,数据已经不重要了,关键是要建立一个可用的表。想通过正常的添加model项,以及正常的迁移过程显然DJ是无法满足。于是进行了以下重新建表的过程。
1. 删除原表,切记,原表中的数据全部丢失(PG)
Drop table your_table_name
如果必要,可以去备份一下。因为我的源数据都在,所以全部带着数据就删除了。
即使在这种全部删除的情况下,如果直接运行migrate,依旧会报错。
2. 通过sql,新建一个表
CREATE TABLE IF NOT EXISTS your_table_name
{
id integer primary key,
...
}
TABLESPACE pg_default;
ALTER TABLE your_table_name OWNER to postgres;
3. 该表中的新主键改为使用自增id的方式
建sequence,这里起名为:your_table_name_id_seq
CREATE SEQUENCE your_table_name_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
4. 将sequence授予新表的primay key
alter table your_table_name alter column id set default nextval('your_table_name_id_seq');
到此为止,新的表已经建立完整,空的。此时DJ这边还是无法使用。
5. 修改该表对应的models下的app的迁移文件
在迁移文件migrations文件夹下查找包括有该model名称的迁移文件,从0001_initial.py开始。
找到有最开始定义该表中的主键内容的这个表,修改为一般的键值,然后添加以id为自增方式的主键。
migrations.CreateModel(
name='your_table_name',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)),
...
]
这里的id为新加的,原来的主键改为一般的表列名即可
6. 删除之前迁移出错的记录
如果在前面的操作之前有迁移出错的记录,此时可以找到相应的迁移文件。这些都在一个app的目录migrations下。
出错提示,无非是“已存在主键,无法操作之类”,或者是“没有建立联系”什么的。主要是找到运行:python manage.py makemigrations时DJ自动在迁移文件中新增的内容:
- 添加新主键的记录
- 修改原主键的记录
migrations.AddField...
migrations.AlterField...
查到后删除相应的迁移文件。》》》提示:正确的目录中,正确的迁移记录文件。用关键词查找,很快可以锁定
7. 重新迁移
此时再进行迁移:
python manage.py makemigrations yourapp
python manage.py migrate --database=db_name_of_yourapp_mapped_to
如果不出意外,迁移就没有问题,可以开始使用新的models了。