如何通过添加新的主键字段来更新django中的模型?

时间:2014-12-01 03:31:40

标签: python django django-models migrate

如何使用自定义主键字段替换Django模型中的默认主键?

我的模型首先没有定义主键,因为django默认会自动将id字段添加为主要字段

#models.py
from django.db import models

class Event(models.Model):
    title = models.CharField(max_length=50, unique=True)
    description = models.CharField(max_length=150)

我在django shell添加了一些对象。

>>e = Event('meeting', 'Contents about meeting')
>>e.save()
>>e = Event('party', 'Contents about party')
>>e.save()

然后我需要将自定义字符字段作为主要字段添加到此模型中。

class Event(models.Model):
    event-id = models.CharField(max_length=50, primary_key=True)
    ...

运行 makemigrations

$ python manage.py makemigrations
You are trying to add a non-nullable field 'event-id' to event without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
 1) Provide a one-off default now (will be set on all existing rows)
 2) Quit, and let me add a default in models.py
Select an option: 1
Please enter the default value now, as valid Python
The datetime and `django.utils.timezone modules` are available, so you can do e.g. timezone.now()
>>> 'meetings'
Migrations for 'blog':
  0002_auto_20141201_0301.py:
    - Remove field id from event
    - Add field event-id to event

但在运行迁移时,却出现了错误:

.virtualenvs/env/local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 485, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: blog_event__new.event-id

3 个答案:

答案 0 :(得分:1)

根据我的经验(在这里使用Django 1.8。*),我在尝试为已经存在的模型更新PK字段时遇到类似的情况,与其他模型有一个外键关系,在后端表中有相关​​数据。

您没有指定此模型是否在FK关系中使用,但似乎是这种情况。

在这种情况下,您获得的错误消息是因为已存在的数据需要与您请求的更改保持一致 - 即。一个新的领域将是PK。这意味着必须删除当前的PK以使django“替换”它们。 (根据docs [1],Django每个模型只支持一个PK字段。)

提供与相关表中当前现有数据匹配的默认值应该有效。

例如:

class Organization(models.Model):
    # assume former PK field no longer here; name is the new PK
    name = models.CharField(primary_key=True)

class Product(models.Model):
    name = models.CharField(primary_key=True)
    organization = models.ForeignKey(Organization)

如果您要更新Organization模型并且产品已存在,则必须更新现有产品行以引用有效的Organization PK值。在迁移过程中,您需要选择一个现有的Organization PK(例如“R& D”)来更新现有产品。

[1] https://docs.djangoproject.com/en/1.8/topics/db/models/#automatic-primary-key-fields

答案 1 :(得分:0)

Django已经在你的后端建立了一个自动递增的整数id作为主键,当你创建了以前的模型时。

当您尝试运行新模型时,尝试重新创建失败的新主键列。

另一个原因是,当你创建字段时,Django期望为每个新行明确定义一个它无法找到的唯一值,因此就是原因。

正如前面的回答中所说,你可以重新创建迁移,然后再尝试一下。它应该工作..干杯: - )

答案 2 :(得分:-2)

问题是您使该字段唯一,然后尝试对表中的所有行使用相同的值。我不确定是否有一种以编程方式提供密钥的方法,但您可以执行以下操作:

  • 删除迁移
  • 从字段
  • 中删除primary_key属性
  • 进行新迁移
  • 应用
  • 填写所有行的值
  • 将primary_key属性添加到字段
  • 进行新迁移
  • 应用

这是暴力行为,但应该运作良好。

祝你好运!