将PositiveIntegerField迁移到FloatField

时间:2019-02-01 21:42:56

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

我有一个现有的填充数据库,并且想将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数据库的支持。

2 个答案:

答案 0 :(得分:3)

这将需要完全重写数据库列吗?

不,不会。我在PostgreSQL,MySQL和SQLite上进行了实验,在每种情况下,从整数到浮点的转换都进行得很好,我还把一些值设置为null以匹配您的情况。

如果您有一个值3,它将变为3.0

如果绝大多数值为空,它将如何缩放?

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

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

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

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

...您首先可以使用sqlmigrate了解迁移SQL,当然,您可以备份数据库。

答案 1 :(得分:1)

您可以使用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了解详情。