2015-03-05 3 views
6

Я работаю с Postgres в приложении Django, и я хочу сделать изменение модели, сбросив строку, чтобы она больше не являлась основным ключом.Перенос Django: создание строки не первичного ключа, получение «ProgrammingError: несколько значений по умолчанию»?

Это то, что моя модель в настоящее время выглядит в Django:

class Meeting(TimeStampedModel): 
    row = models.CharField(max_length=20, primary_key=True) 
    total_items = models.IntegerField() 

Я бежал django-admin.py flush, чтобы удалить все данные из базы данных. Если я запустил python manage.py makemigrations, я вижу No changes detected. Поэтому мы начинаем с чистой базы.

Теперь я редактировать row в models.py так это уже не первичный ключ:

row = models.CharField(max_length=20) 

И запустить 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 

Это кажется запустите ОК. Тогда, если я бегу 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" 

Почему это говорит мне, что у 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, 
     ), 
    ] 
+0

Мне пришлось просто удалить мои ранее существовавшие миграции. –

ответ

8

Попробуйте использовать промежуточную миграцию для достижения этой цели:

1) Добавить id = models.IntegerField() к вашей модели. Пробег makemigrations, а затем migrate.

2) Удалить primary_key = True из поля «row», а также удалить поле «id». Снова запустите makemigrations и migrate.

+4

Это, как правило, работает, спасибо, но: 1) Кажется более аккуратным вписывать их в одну миграцию вручную; 2) Если у вас есть данные в вашей таблице, вам нужно заполнить вновь созданный столбец «id» уникальными значениями и заранее выполнить автоматическую последовательность перед шагом 2; 3) Если какие-либо другие таблицы имеют ограничения внешнего ключа, указывающие на этот ключ, вам необходимо удалить их до шага 2 и вручную добавить новые после шага 2 –