Не удалось выполнить миграцию django db с помощью postgres

Я внес некоторые изменения в мои модели, а затем запустил

python manage.py makemigrations  python manage.py migrate

и я получил эту трассировку:

Operations to perform:
  Synchronize unmigrated apps: staticfiles, messages
  Apply all migrations: sessions, admin, study, auth, quiz, contenttypes, main
Synchronizing apps without migrations:
  Creating tables...
    Running deferred SQL...
  Installing custom SQL...
Running migrations:
  Rendering model states... DONE
  Applying quiz.0013_auto_20151005_0644...Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 330, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 393, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 444, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/commands/migrate.py", line 222, in handle
    executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/executor.py", line 110, in migrate
    self.apply_migration(states[migration], migration, fake=fake, fake_initial=fake_initial)
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/executor.py", line 154, in apply_migration
    self.recorder.record_applied(migration.app_label, migration.name)
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/recorder.py", line 67, in record_applied
    self.migration_qs.create(app=app, name=name)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 348, in create
    obj.save(force_insert=True, using=self.db)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 734, in save
    force_update=force_update, update_fields=update_fields)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 762, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 846, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 885, in _do_insert
    using=using, raw=raw)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py", line 127, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 920, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py", line 974, in execute_sql
    cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/utils.py", line 97, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
django.db.utils.IntegrityError: duplicate key value violates unique constraint "django_migrations_pkey"
DETAIL:  Key (id)=(27) already exists.

Я не знал, как интерпретировать ошибку, что первичный ключ уже существует. Как ни странно, это добавило поле в базу данных, потому что я видел его вывод на моем сайте, и когда я запускал оболочку, я мог видеть, что поля были добавлены, и данные по умолчанию, которые я выбрал, были заполнены.

Я решил снова запустить миграцию, чтобы проверить, пройдет ли он второй раз, и у меня получится другая трассировка...

   Operations to perform:
  Synchronize unmigrated apps: staticfiles, messages
  Apply all migrations: sessions, admin, study, auth, quiz, contenttypes, main
Synchronizing apps without migrations:
  Creating tables...
    Running deferred SQL...
  Installing custom SQL...
Running migrations:
  Rendering model states... DONE
  Applying quiz.0013_auto_20151005_0644...Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 338, in execute_from_command_line
    utility.execute()
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 330, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 393, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 444, in execute
    output = self.handle(*args, **options)
  File "/usr/local/lib/python2.7/dist-packages/django/core/management/commands/migrate.py", line 222, in handle
    executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/executor.py", line 110, in migrate
    self.apply_migration(states[migration], migration, fake=fake, fake_initial=fake_initial)
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/executor.py", line 148, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/migration.py", line 115, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "/usr/local/lib/python2.7/dist-packages/django/db/migrations/operations/fields.py", line 62, in database_forwards
    field,
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/base/schema.py", line 398, in add_field
    self.execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/base/schema.py", line 111, in execute
    cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/usr/local/lib/python2.7/dist-packages/django/db/utils.py", line 97, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/usr/local/lib/python2.7/dist-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: column "lang1_back_to_choice" of relation "quiz_langpairinstructions" already exists

Теперь, если я попробую снова, я всегда получу второй трассировку. Мне интересно, что я должен делать, чтобы я мог совершать миграции во фьючерсы. Почему я получаю эту ошибку, если все, кажется, прошло гладко в самом db?

Ответ 1

Я упустил имя столбца "django_migrations_pkey", и я не понял, что было в базе данных. Каким-то образом джанго был на один шаг ниже фактической базы данных и пытался использовать первичный ключ (pk = 27) вместо числа, на котором он был фактически (что должно было быть 28)

Я не знал, как изменить это изнутри django, поэтому вместо этого я просто удалил последний столбец из базы данных, поэтому он был одним из основных ключей короче и на дорожке с django, и он начал работать нормально.

Ответ 2

Есть и другой способ. Поскольку вы знаете последнее значение id в таблице django_migrations, скажем, что оно равно 100. Затем вам нужно сделать следующее:

ALTER SEQUENCE django_migrations_id_seq RESTART WITH 101;

Ответ 3

Я получил эту ошибку после того, как я вручную вручную переделал записи таблиц миграции django (после того, как некоторые ранее изворотливые миграции были добавлены, затем удалены).

Это оставило идентификаторы django_migrations не в порядке (так сказать) с положением позиции по умолчанию в таблице django_migrations.

Проблема заключается в том, что django принимает идентификатор последней записи и +1 для создания новой записи (в таблице ниже: 197 + 1 = 198), однако, как вы видите, Key (id) = (198) уже существует в таблице.

187 | foo_app             | 0016_auto_20161220_2332                     | 2017-01-06 05:22:07.666172+00
198 | bar_app             | 0004_auto_20160423_2122                     | 2017-01-13 05:38:31.922738+00
197 | baz_app             | 0013_auto_20170203_2311                     | 2017-02-08 18:50:22.70143+00

Как вы можете видеть, цифры для первичного ключа слева не соответствуют порядку. Что я сделал, так это вручную удалить записи из порядка в django_migration, а затем повторно добавить их.

DELETE from django_migrations where name = '0004_auto_20160423_2122';
DELETE from django_migrations where name = '0013_auto_20170203_2311';

INSERT INTO django_migrations VALUES (188, 'baz_app', '0013_auto_20170203_2311', date());
INSERT INTO django_migrations VALUES (189, 'bar_app', '0004_auto_20160423_2122', date());

Также следует отметить, что миграция, которую я изначально пыталась добавить "new_app, 0002_auto_00000000_1111", фактически изменила таблицу new_app в postgres, однако таблица django_migrations не обновилась.

Итак, во второй раз, когда я попытался перезапустить миграцию 0002_auto_00000000_1111, я получил ошибку:

django.db.utils.ProgrammingError: column "new_app_field" of relation "new_app_new" already exists

Мое решение выше исправило проблему для меня.

Ответ 4

Просто переиндексация таблицы django_migrations сработала для меня.

Выполните следующие действия в своем терминале

Сменить пользователя на root

$ sudo su

Чтобы затем вы сменили пользователя на postgres

$ su postgres

Откройте клиент терминала Postgres с выбранной базой данных

$ psql name_of_your_db

В клиенте postgres введите следующую команду

REINDEX TABLE django_migrations;

А затем выйдите из клиента postgres

\q