删除模型继承,并将ID保存在新创建的自动场中



我有一个从非摘要超级模型继承的模型:

class Person(models.Model):
    pass
class User(Person):
    pass

由于构思错误,我们想删除人模型,并将所有人数据复制到用户。主要问题涉及" ID" Autofield。

用户模型没有DJANGO自动加剧的任何ID字段。由于继承,用户的主要密钥是" Person_ptr_id"。

我正在尝试进行数据库迁移。Django迁移希望将" ID"字段添加为Autofield,但要求默认值。我希望每个用户记录从person_ptr_id复制初始值。我也希望邮政序列与值同步。

您是否已经执行过此类迁移?

我终于成功地完成了这些迁移的方法:

1(通过评论person_ptr的列删除和'id'的列创建列来更改Django的自动迁移。然后添加一个" ID"列作为整数:

migrations.AddField(
    model_name='user',
    name='id',
    field=models.IntegerField(null=True)
),

2(创建一个新的空迁移,用于将数据迁移到用户,删除Person_Ptr字段并将" ID"类型更改为autofield

def copy_persons_data(apps, schema_editor):
    User = apps.get_model("accounts", "User")
    Person = apps.get_model("persons", "Person")
    for user in User.objects.all():
        person = Person.objects.get(id=user.person_ptr_id)
        user.new_field1 = person.new_field1
        user.new_field2 = person.new_field2
        user.id = person.id
        user.save()
class Migration(migrations.Migration):
    dependencies = [
        ('accounts', '0026_auto_20170606_1524'),
    ]
    operations = [
        migrations.RunPython(copy_persons_data, reverse_code=migrations.RunPython.noop),
        migrations.RemoveField(
            model_name='user',
            name='person_ptr',
        ),
        migrations.AlterField(
            model_name='user',
            name='id',
            field=models.AutoField(auto_created=True, null=False, primary_key=True, serialize=False, verbose_name='ID'),
            preserve_default=False,
        ),
    ]

这样做,Django将自动创建与最大ID同步的" ID"字段的序列。

注意:

在Datamigration功能中使用user.person_ptr将使Django拒绝保存用户,因为未保存的人实例。因此,我要查询以获取用户的persions实例。

perserve_default = false对于避免django需要一个新的迁移来删除自动场的默认值

根据我的经验,最有效的是:

  • 重命名旧模型并为其创建迁移。
  • 用正确的层次结构重新创建新模型,再次为其创建一个迁移。
  • 创建数据迁移并填充具有较旧值的新模型。
  • 删除旧型号并再次迁移。

到目前为止,这是不太曲折的道路。希望它能帮助有同样问题的人。

最新更新