如何从自定义主键迁移到默认ID [英] How to migrate from custom primary key to default id

查看:96
本文介绍了如何从自定义主键迁移到默认ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个使用电子邮件地址作为自定义主键的模型,如下所示:

I have created a model with email address as custom primary key as follows:

email = models.EmailField(max_length=255, primary_key=True,)

现在我意识到这对我来说不是一个好主意,我想回到自动生成的id字段作为主键。

Now I realized that this is not a good idea in my case and I would like to go back to the automatically generated id field as primary key.

该怎么做?我尝试了不同的方法,但是都失败了。我正在将Django 1.10.4与带有SQLite数据库的Python 3.4.3配合使用。

How to do this? I tried this in different ways but all failed. I am using Django 1.10.4 with Python 3.4.3 with an SQLite database.


  1. 我只是将primary_key = True选项替换为unique =真正。 python manage.py makemigrations 抱怨:

  1. I just replaced the primary_key=True option by unique=True. python manage.py makemigrations complains:

您正在尝试添加非-null字段'id'给用户,没有默认值;我们无法做到这一点(数据库需要一些东西来填充现有行)。

You are trying to add a non-nullable field 'id' to user without a default; we can't do that (the database needs something to populate existing rows).

如果我将 0 指定为默认值,则 python manage.py migration 失败,出现 django.db.utils.IntegrityError:唯一约束失败:login_user.id

If I specify 0 as default value, python manage.py migrate fails with django.db.utils.IntegrityError: UNIQUE constraint failed: login_user.id


  1. 基于此帖子将主键字段更改为唯一字段我试图手动添加一个自动字段,如下所示:

  1. Based on this post Change Primary Key field to unique field I tried to add an Autofield manually, as in:

id = models.AutoField()

id = models.AutoField()

现在 python manage.py makemigrations 失败,原因是:

login.User.id: (fields.E100) AutoFields must set primary_key=True.

如果我按照错误消息的建议进行操作,则会遇到与第一次尝试相同的问题:缺少默认值。

If I do as suggested by the error message, I get the same issue as in my first try: missing default value.


  1. 我尝试制作一个字段id = IntegerField(unique = True)(遵循Django文档,网址为 https://docs.djangoproject。 com / en / 1.10 / howto / writing-migrations /#migrations-that-add-unique-fields ),然后将字段类型更改为AutoField(primary_key = True)。同时,我需要将email字段更改为unique = True以避免具有两个主键。完成这些更改后, makemigrations 可以正常工作,但 migration 失败并带有追溯,并且此错误: django .db.utils.OperationalError:重复的列名称:id 似乎正在尝试添加其他 id列,不知道为什么。

  1. I tried to make a field id=IntegerField(unique=True) (following Django documentation at https://docs.djangoproject.com/en/1.10/howto/writing-migrations/#migrations-that-add-unique-fields) and then change the field type to AutoField(primary_key=True). At the same time, I need to change the email field to unique=True to avoid having two primary keys. After these changes, makemigrations works fine but migrate fails with a traceback and this error: django.db.utils.OperationalError: duplicate column name: id It seems to be trying to make an additional 'id' column, don't know why.

执行此操作的正确方法是什么?另外,如果成功,引用我的用户的ForeignKey字段是否会正确更新?

What is the correct way to do this? Also, if it succeeds, will ForeignKey fields that refer to my User be updated correctly?

推荐答案

这种情况尤其难以解决在实际上甚至没有真正的ALTER TABLE语句

This situation is hard to tackle particularly on sqlite which actuall doesn't even have a real ALTER TABLE statement


SQLite支持ALTER TABLE的有限子集。 SQLite中的ALTER TABLE
命令允许用户重命名表或向现有表添加新的
列。

SQLite supports a limited subset of ALTER TABLE. The ALTER TABLE command in SQLite allows the user to rename a table or to add a new column to an existing table.

大多数类型的django通过临时表进行更改。因此,您也可以这样做

Most of the type, django is doing the changes via a temp table. So you can do that too

步骤1:创建新模型,就像

class TempModel(models.Model):
    email = models.EmailField(max_length=255)
    # other fields from your existing model

请注意,您不需要显式声明主键字段。只需在电子邮件字段中将其关闭就可以了。

Note that you don't need to explicitly declare a primary key field. Merely switching it off in the email field is sufficient.

步骤2:进行迁移并迁移

步骤3:打开您喜欢的数据库客户端,然后执行以下操作:

Step 3: open your favourite database client and do a:

INSERT INTO myapp_tempmodel(fields,....) SELECT * FROM myapp_oldmodel

步骤4:删除旧表,进行迁移并迁移

Step 4: delete old table, make migrations and migrate

步骤5:重命名临时表,进行迁移并迁移

Step 5: rename temp table, make migrations and migrate

这篇关于如何从自定义主键迁移到默认ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆