【问题标题】:Remove model inheritance and keep id in newly created autofield删除模型继承并在新创建的自动字段中保留 id
【发布时间】:2017-11-08 11:08:07
【问题描述】:

我有一个继承自非抽象超级模型的模型:

class Person(models.Model):
    pass

class User(Person):
    pass

由于概念错误,我们想要删除 Person 模型并将所有人员数据复制给用户。主要问题涉及“id”AutoField。

用户模型没有 django 自动创建的任何 id 字段。由于继承,用户的主键是“person_ptr_id”。

我正在尝试进行数据库迁移。 Django 迁移希望将“id”字段添加为 AutoField,但要求提供默认值。我想要从 person_ptr_id 为每个用户记录复制的初始值。 我还希望 postgres 序列与值同步。

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

【问题讨论】:

  • 为什么不分多个步骤来做呢?使用所有字段创建一个新模型“NewUser”,然后从 User 模型迁移数据,然后删除 User 模型并将 NewUser 重命名为 User

标签: python django postgresql inheritance django-migrations


【解决方案1】:

我终于通过这些迁移成功了:

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 拒绝保存用户,因为未保存的 person 实例。所以我做了一个 get 查询来获取用户的 person 实例。

perserve_default=false 对于避免 django 需要新的迁移来删除自动字段的默认值很重要

【讨论】:

  • django.core.exceptions.FieldError: 类 '' 中的本地字段 u'id' 与基类 '' 中类似名称的字段冲突如果我试图为子类创建一个 id 字段
猜你喜欢
  • 2012-05-04
  • 1970-01-01
  • 2022-09-23
  • 1970-01-01
  • 2020-11-04
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多