Django迁移:使行不是主键,得到"ProgrammingError:多个默认值"?

Ric*_*ard 7 django django-migrations

我正在使用Postgres的Django应用程序,我想进行模型更改,重置一行,使其不再是主键.

这就是我的模型目前在Django中的样子:

class Meeting(TimeStampedModel):
    row = models.CharField(max_length=20, primary_key=True)
    total_items = models.IntegerField()
Run Code Online (Sandbox Code Playgroud)

我已经运行django-admin.py flush从数据库中删除所有数据.如果我跑,python manage.py makemigrations我明白了No changes detected.所以我们从干净的基础开始.

现在我row在models.py中编辑,因此它不再是主键:

row = models.CharField(max_length=20)
Run Code Online (Sandbox Code Playgroud)

当被问到时,运行python manage.py makemigrations并设置1为默认值:

You are trying to add a non-nullable field 'id' to meeting 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()
>>> 1
Migrations for 'frontend':
  0007_auto_20150305_1129.py:
    - Add field id to meeting
    - Alter field row on meeting
Run Code Online (Sandbox Code Playgroud)

这似乎运行正常.如果我跑python manage.py migrate:

$ python manage.py migrate
Operations to perform:
  Synchronize unmigrated apps: debug_toolbar
  Apply all migrations: contenttypes, frontend, sites, auth, sessions
Synchronizing apps without migrations:
  Creating tables...
  Installing custom SQL...
  Installing indexes...
Running migrations:
  Applying frontend.0007_auto_20150305_1129...Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/Users/me/.virtualenvs/meetings/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
    utility.execute()
  ...
  File "/Users/me/.virtualenvs/meetings/lib/python2.7/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: multiple default values specified for column "id" of table "frontend_meeting"
Run Code Online (Sandbox Code Playgroud)

为什么告诉我我有multiple default values

我是否需要将唯一的主键值设置为默认值 - 如果是,我该怎么做?

这是迁移文件的样子:

class Migration(migrations.Migration):

    dependencies = [
        ('frontend', '0006_auto_20150305_1050'),
    ]

    operations = [
        migrations.AddField(
            model_name='meeting',
            name='id',
            field=models.AutoField(auto_created=True, primary_key=True, default=1, serialize=False, verbose_name='ID'),
            preserve_default=False,
        ),
        migrations.AlterField(
            model_name='meeting',
            name='row',
            field=models.CharField(max_length=20),
            preserve_default=True,
        ),
    ]
Run Code Online (Sandbox Code Playgroud)

小智 11

尝试使用中间迁移来实现此目的:

1)添加id = models.IntegerField()到您的模型.运行makemigrations然后迁移.

2)从'row'-field中删除primary_key = True,并删除'id'-field.再次运行makemigrations迁移.

  • 这通常有效,谢谢,但是:1)将这些迁移到手动迁移中似乎更整洁; 2)如果表中有数据,则需要在新创建的`id`列中填入唯一值,并在步骤2之前相应地推进自动序列; 3)如果任何其他表具有指向该键的外键约束,则需要在步骤2之前删除它们并在步骤2之后手动添加新键 (4认同)