在South中,我可以将旧列的值复制到新列吗?

2 投票
1 回答
1931 浏览
提问于 2025-04-16 22:45

我有一个Django模型,它是一个子类,我想把它的父类换成一个和原来非常相似的类。具体来说,新的父类描述的是同一个对象,并且有相同的主键。我该怎么做才能让South创建一个新的OneToOne字段,并把旧字段里的值复制到新字段里呢?

1 个回答

11

在South这个工具里,有两种迁移方式:一种是结构迁移,另一种是数据迁移。

当你创建好结构迁移后,接下来要创建一个对应的数据迁移:

./manage.py datamigration <app> <migration_name>

这时候不要运行迁移(还不需要)。相反,打开你刚才创建的迁移文件。

你会看到一个叫做 forwards() 的方法。在这个方法里,你需要定义一个过程,把旧表里的数据复制到新表里。

如果你要把某个表的结构改得更复杂,通常的做法是先进行两次结构迁移,然后再进行一次数据迁移:第一次结构迁移是添加新字段,数据迁移是把旧字段的数据转到新字段里,最后第二次结构迁移则是删除旧字段。通过 forwards() 方法,你可以对数据库做很多事情,只要记得你在访问哪个结构(旧的还是新的)。一般来说,你只会从 orm. 相关的地方读取数据,而写入则使用传统的Django访问方式。

South数据迁移教程对此有详细的讲解。它教你如何使用South的 orm 来访问数据库,这样在结构迁移之前就能使用数据库,而不会因为Django不理解某些字段而出错。

如果你要重命名一个类,这可能会比较麻烦——这涉及到创建新表、从旧表迁移到新表,然后删除旧表。South可以做到这一点,但可能需要多次进行结构和数据迁移。

South还有一个 backwards() 方法,可以让你把数据库表恢复到之前的状态。在某些情况下,这可能是做不到的;因为新表可能记录了一些在降级时会丢失的信息。如果你不在调试模式下,我建议在 backwards() 方法里抛出一个异常。

撰写回答