【问题标题】:Migrate a PositiveIntegerField to a FloatField将 PositiveIntegerField 迁移到 FloatField
【发布时间】:2019-06-26 12:06:36
【问题描述】:

我有一个现有的填充数据库,想将PositiveIntegerField 转换为FloatField。我正在考虑简单地进行迁移:

    migrations.AlterField(
        model_name='mymodel',
        name='field_to_convert',
        field=models.FloatField(
            blank=True,
            help_text='my helpful text',
            null=True),
    ),

该字段当前定义为:

field_to_convert = models.PositiveIntegerField(
    null=True,
    blank=True,
    help_text='my helpful text')

这是否需要完全重写数据库列?这种转换对于大型数据库的规模有多大?如果绝大多数值是null,它会如何扩展?在什么情况下这种转换会失败?如果有影响的话,这是由 Postgres 数据库支持的。

【问题讨论】:

    标签: django database postgresql django-models django-migrations


    【解决方案1】:

    这是否需要完全重写数据库列?

    不,不会。我对 PostgreSQL、MySQL 和 SQLite 做了一个实验,从整数到浮点数的转换在每种情况下都很顺利,我还将一些值设置为 null 以匹配您的情况。

    如果您有一个值3,它只会更改为3.0

    如果绝大多数值为空,它会如何扩展?

    好吧,既然您在字段的配置中保留了null=True,所有空值都将保持为空,这没有问题。如果您删除 null=True,您可能需要指定一个 default 值。

    这种转换在什么情况下会失败?

    获取一个 int 列并将其转换为 float(实数)应该不会失败,如果您发现一个离奇、怪异且非常特殊的情况,那将是一个非常大的发现。

    如果您对迁移结果有疑问...

    ...你可以先用sqlmigrate查看迁移SQL,当然你也可以备份你的数据库。

    【讨论】:

      【解决方案2】:

      您可以使用sqlmigrate 检查为您的迁移生成的 sql。

      $ python manage.py sqlmigrate app_label migration_name

      请记住,它的输出取决于 Django 版本和您在设置中拥有的数据库。对于我手头的迁移设置(Django 1.11、Postgres 9.3),我得到了:

      BEGIN;
      --
      -- Alter field field_to_convert on mymodel
      --
      ALTER TABLE "myapp_mymodel" DROP CONSTRAINT "myapp_mymodel_field_to_convert_check";
      ALTER TABLE "myapp_mymodel" ALTER COLUMN "field_to_convert" TYPE double precision USING "field_to_convert"::double precision;
      COMMIT;
      

      在性能和可靠性方面对我来说都不错。我会说继续使用 AlterField。

      如果您想更加安全,您可以随时执行:重命名字段 -> 创建字段 -> 运行 python -> 删除字段。这将使您能够更好地控制迁移过程。详情请查看this answer

      【讨论】:

        猜你喜欢
        • 2012-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-04
        • 2020-10-11
        • 2016-01-27
        • 2014-07-15
        • 2020-07-20
        相关资源
        最近更新 更多