Django south:在数据迁移中改变字段类型

use*_*706 15 django django-south

我是从更改字段CharFieldIntegerField.字段名称保持不变.新创建的字段将基于旧字段.例如,如果旧字段是"L",则它将具有数字"1".我怎样才能在forwards()功能中实现这一目标?

Sim*_*tte 17

正确的方法是将其分解为三次迁移:

  1. 第一个模式迁移,用于添加新IntegerField字段.
  2. 接下来是数据迁移,将源自的数据转换CharFieldIntegerField
  3. 最后的架构迁移,以删除现在未使用的CharField.

如果您希望新添加IntegerField的名称与要删除的名称相同,则可能需要第四个CharField.

如果项目状态IntegerField尚未添加到模型文件中,则应按照以下步骤继续:

  1. 添加IntegerField到您的模型.
  2. 为包含模型的应用程序创建架构迁移.如果新添加的字段不为空,则可能需要为此处指定默认值.
  3. datamigration为包含模型的应用程序创建数据迁移(使用).在forwards()新创建的DataMigration类的方法中记下您的逻辑以转换您的数据.尝试使用updatemanager方法,而不是在可能的情况下迭代所有数据库行.如果你使用dict(比如{'L': 1, ...})声明你的转换逻辑,那么此时应该很容易实现backwards(),因为操作是可逆的.这也是一个很好的练习,以确保你不会忽视一个简单的案例forwards()- 它在过去帮助了我很多次.
  4. CharField从模型中删除.
  5. 为包含模型的应用程序创建模式迁移,以便DROP现在使用未使用的列.

将此操作分解为三次迁移而不是在空白模板中写下整个逻辑的事实具有以下几个优点:

  1. 自动生成的DDL操作:ADD/ DROP逻辑已由South自动生成,您不必担心在数据库列中引入拼写错误.
  2. 完全可逆的操作:如果您花时间实施DataMigration.backwards()转换步骤,您应该能够完全逆转整个操作.如果您需要回滚到代码的先前版本并且在更新生产代码库时作为安全网络,这对于测试目的而言非常方便.
  3. 操作的原子性:每个操作被隔离并在其自己的事务中运行的事实不会使您在数据库和South迁移之间处于不一致状态.例如,如果所有操作都是在单个迁​​移中执行的(在forwards()本例中采用相同的方法),并且在数据迁移步骤期间引发了异常(例如,KeyError因为转换中的未处理值dict).如果您使用的ORDBMS是不支持事务模式更改的服务器,那么在修复数据迁移部件后,您将无法立即重新运行迁移,您必须自己手动删除新添加的IntegerField列.同样,这是迁移生产数据库时不想处理的事情.
  4. 能够执行干运行:在迁移生产数据库时也非常方便.

  • 这就是我最终做的事情.这类似于[South migration DateField to IntegerField](http://stackoverflow.com/questions/22413806/south-migrate-datefield-to-integerfield). (2认同)