将具有默认值的Django字段迁移到PostgreSQL数据库

7

https://docs.djangoproject.com/en/1.10/topics/migrations/

这里说: "在模式支持方面,PostgreSQL是所有数据库中最有能力的;唯一的注意点是添加具有默认值的列将导致表的完全重写,时间与其大小成比例。"
"因此,建议您始终使用null=True创建新列,这样它们将立即添加。"
我想知道我是否理解正确。 从我理解的来看,我应该首先使用null=True和没有默认值创建字段,然后迁移它,然后再给它一个默认值并再次迁移,这样值将立即添加,否则整个数据库将被重写,而Django迁移不能自行完成此操作?
2个回答

5
在同一页面中还提到了以下内容:
此外,MySQL 几乎会为每个模式操作完全重写表,并且通常需要的时间与表中的行数成正比。在较慢的硬件上,每百万行可能超过一分钟 - 向仅有几百万行的表添加几列可能会锁定您的站点超过十分钟。
而且,
SQLite 几乎没有内置的模式更改支持,因此 Django 尝试通过以下方式进行模拟:
创建一个新表并使用新模式复制数据
删除旧表
将新表重命名以匹配原始名称
简而言之,上述语句真正意思是postgresql在添加具有默认值的新列时表现出mysql类似的行为。
您尝试的方法是可行的。添加一个空列意味着不需要重写表。然后,您可以更改列以具有默认值。但是,现有的空值将继续保持为空。

我的意思是编写数据迁移并修改现有的空值。 - Ali Ankarali
1
更新查询将空值替换为默认值比DDL更快。 - e4c5
1
很高兴能够提供帮助。祝你的项目一切顺利。 - e4c5

1
据我理解,在第二次迁移中,将不会将默认值写入现有行。只有当创建没有默认字段值的新行时,才会写入默认值。
我认为对于新列使用null=True的警告仅与性能有关。如果您确实希望所有现有行都具有默认值,请使用default=并接受表重写的性能后果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接