django 模型在没有停机时间的情况下将 OneToOneField 更改为 ForeignKey

django model change OneToOneField to ForeignKey with no DownTime

我将我的 django 模型的一个字段设为 OneToOneField。因此,不可能存储重复的 FK 值。我认为将 OneToOneField 更改为 ForeignKey 是解决方案。


当前

class MyModel(models.Model):
    ...
    abc = models.OneToOneField(YourModel, related_name='my_model', blank=True, null=True, on_delete=models.CASCADE)
    ...

未来

class MyModel(models.Model):
    ...
    abc = models.ForeignKey(YourModel, related_name='my_model', blank=True, null=True, on_delete=models.CASCADE)
    ...

问题是迁移时停机。这个模型是我服务中的一个重要模型,很多请求都是瞬间进来的。它也有很多数据。
有没有办法在不停机的情况下解决这个问题?

我的服务使用 mysql 5.6 和 django 2.2。

选项 a)

嗯,所以在 DB 关系方面我看不出有什么不同,那么如果您只是调整模型定义中的字段并修改最初创建该字段的旧迁移呢?这样Django应该认为没有什么新东西可以应用并将原始的OneToOne Field视为ForeignKey Field

请先在备份上尝试,看看是否有额外的唯一约束,或者在您拥有真正的外键字段之前,您可能必须在自定义 sql 命令中删除。

选项 b)

使用多个迁移和部署。

  • 首先添加一个新字段(例如 abc_new 可以为空)
  • 调整您的逻辑,以便始终为新数据和更改填充两个字段
  • 在新版本中部署它
  • 将“旧”数据从 abc 复制到 abc_new
  • 此时您有两行包含完全相同的数据
  • 创建一个新版本,删除旧的 abc 列并将 abc_new 重命名为 abc 并删除包含 abc_new 的此“同步”逻辑的逻辑字段