【问题标题】:Migration of Django field with default value to PostgreSQL database将具有默认值的 Django 字段迁移到 PostgreSQL 数据库
【发布时间】:2017-05-21 00:24:56
【问题描述】:
https://docs.djangoproject.com/en/1.10/topics/migrations/
这里说:
“就模式支持而言,PostgreSQL 是这里所有数据库中能力最强的;唯一需要注意的是,添加具有默认值的列将导致表的完全重写,时间与其大小成正比。
“因此,建议您始终使用 null=True 创建新列,因为这样会立即添加它们。”
我问我是否正确。
据我了解,我应该首先创建具有 null=True 且没有默认值的字段然后迁移它,然后给它一个默认值并再次迁移它,这些值将立即添加,否则整个数据库都会被重写,而 Django 迁移不想自己做这个伎俩?
【问题讨论】:
标签:
python
django
postgresql
django-migrations
【解决方案1】:
按照我的理解,在第二次迁移时,默认值不会写入现有行。仅当创建一个没有默认字段值的新行时,才会写入该行。
我认为对新列使用 null=True 的警告仅与性能有关。如果您真的希望所有现有行都具有默认值,只需使用 default= 并接受表重写的性能后果。
【解决方案2】:
在同一页面中还提到:
此外,MySQL 将完全重写几乎所有模式的表
操作,通常需要与数量成正比的时间
表中的行以添加或删除列。在较慢的硬件上,这
每百万行可能比一分钟更糟糕 - 添加几列
只有几百万行的表可能会锁定您的网站超过
十分钟。
和
SQLite 几乎没有内置的架构更改支持,因此
Django 尝试通过以下方式模拟它:
使用新架构创建新表
删除旧表重命名新表以匹配原始表
名字
所以简而言之,你上面提到的那句话真正说的是
postgresql 在添加新列时表现出类似 mysql 的行为
默认值
您尝试的方法会奏效。添加带有 null 的列将意味着不会重写表。然后,您可以将该列更改为具有默认值。然而现有的空值将继续为空