Python django型号将OneToOneField更改为ForeignKey,无需停机

Python django型号将OneToOneField更改为ForeignKey,无需停机,python,mysql,django,django-models,database-migration,Python,Mysql,Django,Django Models,Database Migration,我将django模型的一个字段作为OneToOneField。因此,不可能存储重复的FK值。我认为将OneToOneField改为ForeignKey是解决方案 现在的 类MyModel(models.Model): ... abc=models.OneToOneField(您的模型,相关的\u name='my\u model',blank=True,null=True,on\u delete=models.CASCADE) ... 未来 类MyModel(models.Model): .

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


现在的
类MyModel(models.Model):
...
abc=models.OneToOneField(您的模型,相关的\u name='my\u model',blank=True,null=True,on\u delete=models.CASCADE)
...
未来
类MyModel(models.Model):
...
abc=models.ForeignKey(YourModel,related\u name='my\u model',blank=True,null=True,on\u delete=models.CASCADE)
...

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

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

选项a)

嗯,从数据库关系的角度看,我看不出有什么区别,那么,如果您只是调整模型定义中的字段,并修改最初创建该字段的旧迁移,会怎么样?这样,Django应该认为没有什么新东西可以应用,并将原始的OneToOne字段视为ForeignKey字段

请先在备份上尝试此操作,以查看是否存在其他唯一约束,或者在创建真正的ForeignKey字段之前,您可能需要在自定义sql命令中删除这些约束

备选方案b)

使用多个迁移和部署

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