【问题标题】:django.db.utils.IntegrityError: duplicate key value violates unique constraint "django_migrations_pkey"django.db.utils.IntegrityError:重复键值违反唯一约束“django_migrations_pkey”
【发布时间】:2018-12-06 20:34:31
【问题描述】:

我有一个 Django 模型 SessionType,其定义类似于以下内容:

from django import models


class SessionType(models.Model):
    class Meta:
        ordering = ['title']
    title = models.CharField(max_length=255, unique=True)

起初,unique=True 约束不存在;我刚刚添加了它,然后运行python manage.py makemigrations。这导致了以下迁移 (0163_auto_20180627_1309.py):

# -*- coding: utf-8 -*-
# Generated by Django 1.11.9 on 2018-06-27 20:09
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('lucy_web', '0162_merge_20180531_0009'),
    ]

    operations = [
        migrations.AlterField(
            model_name='sessiontype',
            name='title',
            field=models.CharField(max_length=255, unique=True),
        ),
    ]

但是,当我尝试python manage.py migrate 时,我收到以下错误:

django.db.utils.IntegrityError: 重复键值违反唯一约束“django_migrations_pkey” 详细信息:键 (id)=(326) 已存在。

这里是命令和完整的回溯:

(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py makemigrations
Migrations for 'lucy_web':
  lucy_web/migrations/0163_auto_20180627_1309.py
    - Alter field title on sessiontype
(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auditlog, auth, contenttypes, defender, lucy_web, oauth2_provider, otp_static, otp_totp, sessions, two_factor
Running migrations:
  Applying lucy_web.0163_auto_20180627_1309...Traceback (most recent call last):
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
psycopg2.IntegrityError: duplicate key value violates unique constraint "django_migrations_pkey"
DETAIL:  Key (id)=(326) already exists.


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 28, in <module>
    execute_from_command_line(sys.argv)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 356, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/core/management/base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/core/management/base.py", line 330, in execute
    output = self.handle(*args, **options)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 204, in handle
    fake_initial=fake_initial,
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/migrations/executor.py", line 115, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/migrations/executor.py", line 145, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/migrations/executor.py", line 250, in apply_migration
    self.recorder.record_applied(migration.app_label, migration.name)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/migrations/recorder.py", line 73, in record_applied
    self.migration_qs.create(app=app, name=name)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/models/query.py", line 394, in create
    obj.save(force_insert=True, using=self.db)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/models/base.py", line 808, in save
    force_update=force_update, update_fields=update_fields)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/models/base.py", line 838, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/models/base.py", line 924, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/models/base.py", line 963, in _do_insert
    using=using, raw=raw)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/models/query.py", line 1076, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1112, in execute_sql
    cursor.execute(sql, params)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-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)=(326) already exists.

查看数据库,我看到还有一个主键为 326 的迁移:

该迁移0161_auto_20180530_2140.py 还包含SessionType 模型上的AlterField 操作:

# -*- coding: utf-8 -*-
# Generated by Django 1.11.9 on 2018-05-31 04:40
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('lucy_web', '0160_merge_20180524_1507'),
    ]

    operations = [
        migrations.AlterField(
            model_name='sessiontype',
            name='description',
            field=models.TextField(blank=True),
        ),
        migrations.AlterField(
            model_name='sessiontype',
            name='short_description',
            field=models.TextField(blank=True),
        ),
    ]

按照django db migration failed with postgres,我尝试运行命令

ALTER SEQUENCE django_migrations_id_seq RESTART WITH 329;

像这样:

但是,现在当我尝试迁移时,我遇到了另一个错误,即某个唯一约束已经存在:

(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auditlog, auth, contenttypes, defender, lucy_web, oauth2_provider, otp_static, otp_totp, sessions, two_factor
Running migrations:
  Applying lucy_web.0163_auto_20180627_1309...Traceback (most recent call last):
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: relation "lucy_web_sessiontype_title_c207e4f8_uniq" already exists


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 28, in <module>
    execute_from_command_line(sys.argv)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/core/management/__init__.py", line 356, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/core/management/base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/core/management/base.py", line 330, in execute
    output = self.handle(*args, **options)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 204, in handle
    fake_initial=fake_initial,
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/migrations/executor.py", line 115, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/migrations/executor.py", line 145, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/migrations/executor.py", line 244, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/migrations/migration.py", line 129, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/migrations/operations/fields.py", line 221, in database_forwards
    schema_editor.alter_field(from_model, from_field, to_field)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 515, in alter_field
    old_db_params, new_db_params, strict)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/backends/postgresql/schema.py", line 112, in _alter_field
    new_db_params, strict,
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 719, in _alter_field
    self.execute(self._create_unique_sql(model, [new_field.column]))
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 120, in execute
    cursor.execute(sql, params)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 79, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: relation "lucy_web_sessiontype_title_c207e4f8_uniq" already exists

我该如何解决这个问题?我应该删除该唯一约束并重新运行迁移吗?

【问题讨论】:

    标签: python django


    【解决方案1】:

    重新启动索引后,我确实只是简单地删除/删除了给出“已经存在”错误的约束和索引并设法迁移:

    (venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py migrate
    Operations to perform:
      Apply all migrations: admin, auditlog, auth, contenttypes, defender, lucy_web, oauth2_provider, otp_static, otp_totp, sessions, two_factor
    Running migrations:
      Applying lucy_web.0163_auto_20180627_1309... OK
    

    【讨论】:

      【解决方案2】:

      此修复适用于我的 postgreSQL 数据库

      打开 django shell

      python manage.py shell
      

      运行以下 Python 代码重置 id

      from django.db import connections
      
      query = "SELECT setval('django_migrations_id_seq', (SELECT MAX(id) FROM django_migrations))"
      cursor = connections['default'].cursor()
      cursor.execute(query) 
      row = cursor.fetchone()
      

      【讨论】:

      • 与标记的答案相比,这是一个更好的答案并且工作正常。
      • 只是一个注释来解释这个答案中发生了什么,因为答案(虽然很好)很简洁:我认为问题是 django 迁移表中的两条记录具有相同的 ID。此命令使用新 ID 设置其中一个,假设 ID 是连续编号的。完成此操作后,所有记录都应具有唯一 ID,并且在您运行迁移时将不再发生错误。
      【解决方案3】:

      重复运行 migrate 命令,直到错误消失。 在每次尝试时,它都会尝试增加 id(pk) 值。 一旦增量达到现有 id 的最大值,命令就会成功运行。

      【讨论】:

        【解决方案4】:

        我使用以下查询修复了我的 Postgres 数据库:

        1. 使用./manage.py dbshell 输入您的数据库shell
        2. 运行SELECT id FROM "django_admin_log" ORDER BY id DESC LIMIT 1; 并记下输出(应该是像326 这样的整数)
        3. 运行 SELECT setval('django_admin_log_id_seq', LASTID + 1); 并将 LASTID 替换为您从上一个命令中获得的整数

        【讨论】:

        • SELECT setval('django_admin_log_id_seq', (SELECT id FROM "django_admin_log" ORDER BY id DESC LIMIT 1) + 1);
        猜你喜欢
        • 2019-07-22
        • 2018-03-28
        • 2013-10-08
        • 2016-04-14
        • 2022-11-05
        • 2014-06-19
        • 2021-01-25
        • 1970-01-01
        • 2022-01-13
        相关资源
        最近更新 更多