如何将 Django 模型字段分解为自己的模型并保留数据?

How to factor out Django model fields into their own model, keeping data?

我有一个像这样的 Django ORM 模型:

class Foo(models.Model):
    data = models.CharField(null=True, blank=True)

    bar_id = models.IntegerField(null=True, blank=True)
    bar_data = models.CharField(null=True, blank=True)

我想将 bar_idbar_data 分解成一个单独的模型 class:

class Foo(models.Model):
    data = models.CharField(null=True, blank=True)
    bar = models.ForeignKey('Bar', null=True, blank=True)

class Bar(models.Model):
    id = models.IntegerField(primary_key=True)
    data = models.CharField(null=True, blank=True)

我已经确定每个 bar_id 只有一个值与 bar_data 关联,如果 bar_id bar_data 总是 None ] 是 None,所以应该可以将旧的 bar_data 字段迁移到新的 Bar 对象中,我只是不知道该怎么做。

我能否在保留数据的同时迁移到这些新模型?

正确的 django-ish 方法是:

  • 使用新模型 (Bar) 创建架构迁移 (https://docs.djangoproject.com/en/1.11/topics/migrations/) - 此迁移应该只添加 Bar 而没有任何实例
  • 创建数据迁移 (https://docs.djangoproject.com/en/1.11/topics/migrations/#data-migrations),将数据从旧模型复制到新模型。您只需要循环所有 Foo 个实例并根据您的要求创建 Bar 个实例。如果确实需要,您还可以尝试为此数据迁移创建向后数据迁移(即循环所有 Bar 个实例并正确更新 Foo 个实例)。请记住,虽然此迁移是 运行,但您将同时拥有 FooBar 以及 Foo 中的 bar_idbar_data 字段。
  • 创建第二个模式迁移,它将从 Foo.
  • 中删除(删除)不需要的字段(bar_idbar_data

正如我所说,这是正确的 django-ish 方法。但是,如果你想要快速而肮脏的东西,你可以查看我的文章,了解如何仅使用 postgresql(使用 PL/pgsql)在你的数据库中进行此类更改:https://spapas.github.io/2017/07/04/postgresql-auto-create-category-column/