将 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的主要内容,如果未能解决你的问题,请参考以下文章