【问题标题】: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 的列将意味着不会重写表。然后,您可以将该列更改为具有默认值。然而现有的空值将继续为空

      【讨论】:

      • 我的意思是写一个数据迁移并修改现有的空值。
      • 用默认值替换空值的更新查询将比 DDL 更快。
      • 很高兴能帮上忙。祝您的项目一切顺利
      猜你喜欢
      • 2014-11-29
      • 2016-09-04
      • 2020-12-01
      • 2023-03-22
      • 2019-07-27
      • 2017-07-11
      • 2019-01-28
      • 2019-01-28
      • 2016-04-26
      相关资源
      最近更新 更多