【发布时间】:2014-05-01 06:11:33
【问题描述】:
我正在将一个字段从 CharField 更改为 IntegerField。字段名称保持不变。新创建的字段将基于旧字段。例如,如果旧字段是“L”,则它会改为使用数字“1”。如何在 forwards() 函数中完成此操作?
【问题讨论】:
标签: django django-south
我正在将一个字段从 CharField 更改为 IntegerField。字段名称保持不变。新创建的字段将基于旧字段。例如,如果旧字段是“L”,则它会改为使用数字“1”。如何在 forwards() 函数中完成此操作?
【问题讨论】:
标签: django django-south
对于同样的情况,我只遵循了 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) 现在应用迁移。
【讨论】:
正确的做法是将其分解为三个迁移:
IntegerField 字段。CharField 的数据转换为IntegerField
CharField。如果您希望新添加的 IntegerField 与要删除的 CharField 同名,则可能需要第四个。
鉴于尚未将IntegerField 添加到您的模型文件的项目状态,您应该按照以下步骤进行操作:
IntegerField 添加到您的模型。datamigration)。在新创建的DataMigration 类的forwards() 方法中,写下转换数据的逻辑。如果可能,请尝试使用 update 管理器方法,而不是遍历所有数据库行。如果您使用dict(比如{'L': 1, ...})声明您的转换逻辑,那么此时实现backwards() 应该也很容易,因为该操作是可逆的。这也是一个很好的练习,可以确保你没有忽略 forwards() 中的一个边缘案例——它在过去帮助了我很多次。CharField。DROP 现在未使用的列。您将此操作分解为三个迁移,而不是在空白模板中写下整个逻辑,这一事实有几个优点:
ADD/DROP 逻辑已由 South 自动生成,您不必担心在数据库列中引入拼写错误。DataMigration.backwards(),您应该能够完全反转整个操作。如果您需要回滚到之前的代码版本并在更新生产代码库时作为安全网,这对于测试目的非常方便。forwards() 方法),并且在数据迁移步骤期间引发了异常(比如 KeyError,因为您的转换中有未处理的值 @987654345 @)。如果您使用不支持事务模式更改的ORDBMS,您将无法在修复数据迁移部分后立即重新运行迁移,您必须手动删除新添加的@987654347 @专栏自己。同样,这是您在迁移生产数据库时不想处理的事情。【讨论】: