【问题标题】:Django south: changing field type in data migrationDjango south:更改数据迁移中的字段类型
【发布时间】:2014-05-01 06:11:33
【问题描述】:

我正在将一个字段从 CharField 更改为 IntegerField。字段名称保持不变。新创建的字段将基于旧字段。例如,如果旧字段是“L”,则它会改为使用数字“1”。如何在 forwards() 函数中完成此操作?

【问题讨论】:

    标签: django django-south


    【解决方案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) 现在应用迁移。

    【讨论】:

      【解决方案2】:

      正确的做法是将其分解为三个迁移:

      1. 第一次架构迁移以添加新的 IntegerField 字段。
      2. 随后进行数据迁移,将源自CharField 的数据转换为IntegerField
      3. 最后的架构迁移以移除现在未使用的CharField

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

      鉴于尚未将IntegerField 添加到您的模型文件的项目状态,您应该按照以下步骤进行操作:

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

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

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

      【讨论】:

      • 这就是我最终要做的。这类似于South migrate DateField to IntegerField
      • 太棒了!争先恐后地写下来,希望你还没有在一次迁移中把它全部压扁。希望我的回答能够让您更深入地了解为什么您应该这样做。
      猜你喜欢
      • 1970-01-01
      • 2012-05-19
      • 2013-04-19
      • 2012-12-28
      • 2017-10-28
      • 2019-02-03
      • 2013-11-19
      • 2014-01-03
      • 1970-01-01
      相关资源
      最近更新 更多