我正在将字段从CharField
更改为IntegerField
。字段名称保持不变。新创建的字段将基于旧字段。例如,如果旧字段是“L”,则它将具有数字“1”。如何在forwards()
函数中完成此操作?
答案 0 :(得分:17)
正确的方法是将其分解为三次迁移:
IntegerField
字段的第一个架构迁移。CharField
的数据转换为IntegerField
CharField
。 如果您希望新添加的IntegerField
与要移除的CharField
具有相同的名称,则可能需要第四个。
如果项目状态中IntegerField
尚未添加到模型文件中,则应按照以下步骤继续:
IntegerField
添加到您的模型中。datamigration
)。在新创建的forwards()
类的DataMigration
方法中,记下转换数据的逻辑。尝试使用update
管理器方法,而不是在可能的情况下迭代所有数据库行。如果您使用dict
(例如{'L': 1, ...}
)声明转换逻辑,那么此时应该很容易实现backwards()
,因为操作是可逆的。这也是一个很好的练习,以确保你没有忽略forwards()
中的一个边缘案例 - 它在过去帮助了我很多次。CharField
。DROP
现在未使用的列。您将此操作分为三次迁移而不是将整个逻辑写入空白模板这一事实有一些优势:
ADD
/ DROP
逻辑,您无需担心在数据库列中引入拼写错误。DataMigration.backwards()
,您应该能够完全颠倒整个操作。如果您需要回滚到代码的先前版本并且在更新生产代码库时作为安全网络,这对于测试目的来说非常方便。forwards()
方法),并且在数据迁移步骤期间引发了异常(比如KeyError
,因为未处理的值您的转化dict
)。如果您使用的ORDBMS
不支持事务模式更改,则在修复数据迁移部分后无法立即重新运行迁移,您必须手动删除新添加的数据迁移部分IntegerField
列自己。同样,这是您在迁移生产数据库时不想处理的事情。答案 1 :(得分:1)
对于同样的情况,我只需要3个步骤。
1)将文件类型从CharField更改为IntegerField,
2)ALTER TABLE the_table ALTER COLUMN col_name TYPE integer USING(col_name :: integer); 或
ALTER TABLE the_table ALTER COLUMN col_name TYPE integer USING(trim(col_name):: integer); #以防你的Char或Text字段中有空格。如果你的表中有数据,那应该是整数字符串。
3)现在应用迁移。