将 PositiveIntegerField 迁移到 FloatField

Posted

技术标签:

【中文标题】将 PositiveIntegerField 迁移到 FloatField【英文标题】:Migrate a PositiveIntegerField to a 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 数据库支持的。

【问题讨论】:

【参考方案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。

【讨论】:

以上是关于将 PositiveIntegerField 迁移到 FloatField的主要内容,如果未能解决你的问题,请参考以下文章

ValueError:字段admin.LogEntry.user是用惰性引用声明的。

Django聚合:两个字段相乘的总和

值错误 - Python Django

将Pod迁移到其他节点

如何将ORACLE的数据迁移到MYSQL

怎么将数据迁移到对象存储OSS?