programing

IntegrityError 중복 키 값이 고유 제약 조건을 위반 함-django / postgres

shortcode 2021. 1. 16. 20:22
반응형

IntegrityError 중복 키 값이 고유 제약 조건을 위반 함-django / postgres


나는 이전 에 내가 구피 / 잘못 작성된 mysql 쿼리에서 postgresql 로의 변환을 모색 했던 질문 에 대해 후속 조치 를 취하고 있습니다. 나는 그것으로 성공했다고 믿는다. 어쨌든 mysql 데이터베이스에서 postgres 데이터베이스로 수동으로 이동 한 데이터를 사용하고 있습니다. 다음과 같은 쿼리를 사용하고 있습니다.

  """
  UPDATE krypdos_coderound cru

  set is_correct = case 
      when t.kv_values1 = t.kv_values2 then True 
      else False 
      end

  from 

  (select cr.id, 
    array_agg(
    case when kv1.code_round_id = cr.id 
    then kv1.option_id 
    else null end 
    ) as kv_values1,

    array_agg(
    case when kv2.code_round_id = cr_m.id 
    then kv2.option_id 
    else null end 
    ) as kv_values2

    from krypdos_coderound cr
     join krypdos_value kv1 on kv1.code_round_id = cr.id
     join krypdos_coderound cr_m 
       on cr_m.object_id=cr.object_id 
       and cr_m.content_type_id =cr.content_type_id 
     join krypdos_value kv2 on kv2.code_round_id = cr_m.id

   WHERE
     cr.is_master= False
     AND cr_m.is_master= True 
     AND cr.object_id=%s 
     AND cr.content_type_id=%s 

   GROUP BY cr.id  
  ) t

where t.id = cru.id
    """ % ( self.object_id, self.content_type.id)
  )

이것이 잘 작동한다고 믿을만한 이유가 있습니다. 그러나 이것은 새로운 문제로 이어졌습니다. 제출하려고 할 때 django에서 다음과 같은 오류가 발생합니다.

IntegrityError at (some url): 
duplicate key value violates unique constraint "krypdos_value_pkey"

여기에 게시 된 몇 가지 답변을 살펴 보았지만 내 문제에 대한 해결책을 찾지 못했습니다 (관련 질문이 흥미로운 읽기를 위해 만들었음에도 불구하고). 내 로그에서 이것을 볼 수 있는데, 이는 내가 명시 적으로 insert를 호출하지 않기 때문에 흥미 롭습니다. django는 그것을 처리해야합니다.

   STATEMENT:  INSERT INTO "krypdos_value" ("code_round_id", "variable_id", "option_id", "confidence", "freetext")
   VALUES (1105935, 11, 55, NULL, E'') 
   RETURNING "krypdos_value"."id"

그러나이를 실행하려고하면 중복 키 오류가 발생합니다. 실제 오류는 아래 코드에서 발생합니다.

 # Delete current coding         CodeRound.objects.filter(object_id=o.id,content_type=object_type,is_master=True).delete()
  code_round = CodeRound(object_id=o.id,content_type=object_type,coded_by=request.user,comments=request.POST.get('_comments',None),is_master=True)
  code_round.save()
  for key in request.POST.keys():
    if key[0] != '_' or key != 'csrfmiddlewaretoken':
      options = request.POST.getlist(key)
      for option in options:
        Value(code_round=code_round,variable_id=key,option_id=option,confidence=request.POST.get('_confidence_'+key, None)).save()  #This is where it dies
  # Resave to set is_correct
  code_round.save()
  o.status = '3' 
  o.save(

시퀀스 등을 확인했는데 순서가있는 것 같습니다. 이 시점에서 나는 무엇을 해야할지 모르겠다. 나는 그것이 장고의 끝에서 무언가라고 생각하지만 확실하지 않다. 어떤 피드백이라도 대단히 감사하겠습니다!


이런 일이 발생했습니다. Postgres에서 기본 키 필드를 다시 동기화해야합니다. 핵심은 SQL 문입니다.

SELECT setval('tablename_id_seq', (SELECT MAX(id) FROM tablename)+1)

MySQL과 SQLite (명시 적 ID가있는 객체를 삽입 할 때도 다음 사용 가능한 기본 키를 업데이트 함) 백엔드와 Postgres, Oracle 등과 같은 다른 백엔드 간의 알려진 동작 차이 인 것 같습니다. .

동일한 문제를 설명하는 티켓이 있습니다 . 유효하지 않은 것으로 닫혔지만 사용 가능한 다음 키를 업데이트하는 Django 관리 명령이 있다는 힌트를 제공합니다.

MyApp 애플리케이션의 모든 다음 ID를 업데이트하는 SQL을 표시하려면 다음을 수행하십시오 .

python manage.py sqlsequencereset MyApp

명령문을 실행하기 위해 dbshell 관리 명령에 대한 입력으로 제공 할 수 있습니다 . bash의 경우 다음을 입력 할 수 있습니다.

python manage.py sqlsequencereset MyApp | python manage.py dbshell

관리 명령의 장점은 기본 DB 백엔드를 추상화하므로 나중에 다른 백엔드로 마이그레이션하더라도 작동한다는 것입니다.


나는 같은 문제가 있었다. "인벤토리"앱에 기존 테이블이 있고 django 관리자에 새 레코드를 추가하고 싶었는데 다음 메시지가 표시됩니다.

중복 키 값이 고유 제약 조건 "inventory_part_pkey"를 위반합니다. DETAIL : 키 (part_id) = (1)이 이미 있습니다.

앞서 언급했듯이 아래 코드를 실행하여 id-s를 재설정하는 SQL 명령을 생성하십시오.

python manage.py sqlsequencereset inventory

제 경우 python manage.py sqlsequencereset MyApp | python manage.py dbshell에는 작동하지 않았습니다.

  • 그래서 생성 된 SQL 문을 복사했습니다.
  • 그런 다음 postgreSQL 용 pgAdmin을 열고 내 db를 열었습니다.
  • 6. 아이콘 클릭 (임의의 SQL 쿼리 실행)
  • 생성 된 내용을 복사했습니다.

제 경우에는 다음과 같습니다.

BEGIN; SELECT setval (pg_get_serial_sequence ( ' "inventory_signup"', 'id'), coalesce (max ( "id"), 1), max ( "id")는 null이 아님) FROM "inventory_signup"; SELECT setval (pg_get_serial_sequence ( ' "inventory_supplier"', 'id'), coalesce (max ( "id"), 1), max ( "id")는 null이 아님) FROM "inventory_supplier"; 범하다;

F5로 실행했습니다.

이것은 내 모든 테이블을 수정하고 마지막으로 더 이상 id = 1에 추가하지 않고 새 레코드를 끝에 추가합니다.


zapphods 답변 외에도 :

제 경우에는 모든 마이그레이션을 삭제했기 때문에 인덱싱이 실제로 올바르지 않았으며, 마이그레이션 단계에 있지 않았기 때문에 개발할 때 데이터베이스는 아마도 10-15 회 정도였습니다.

IntegrityError가 발생했습니다. finished_product_template_finishedproduct_pkey

테이블을 다시 색인화하고 runserver를 다시 시작하십시오.

I was using pgadmin3 and for whichever index was incorrect and throwing duplicate key errors I navigated to the constraints and reindexed.

여기에 이미지 설명 입력

And then reindexed.

여기에 이미지 설명 입력


The solution is that you need to resync your primary key fields as reported by "Hacking Life" who wrote an example SQL code but, as suggested by "Ad N" is better to run the Django command sqlsequencereset to get the exact SQL code that you can copy and past or run with another command.

As a further improvement to these answers I would suggest to you and other reader to dont' copy and paste the SQL code but, more safely, to execute the SQL query generated by sqlsequencereset from within your python code in this way (using the default database):

from django.core.management.color import no_style
from django.db import connection

from myapps.models import MyModel1, MyModel2


sequence_sql = connection.ops.sequence_reset_sql(no_style(), [MyModel1, MyModel2])
with connection.cursor() as cursor:
    for sql in sequence_sql:
        cursor.execute(sql)

I tested this code with Python3.6, Django 2.0 and PostgreSQL 10.


If you have manually copied the databases, you may be running into the issue described here.


I encountered this error because I was passing extra arguments to the save method in the wrong way.

For anybody who encounters this, try forcing UPDATE with:

instance_name.save(..., force_update=True)

If you get an error that you cannot pass force_insert and force_update at the same time, you're probably passing some custom arguments the wrong way, like I did.


If you want to reset the PK on all of your tables, like me, you can use the PostgreSQL recommended way:

SELECT 'SELECT SETVAL(' ||
       quote_literal(quote_ident(PGT.schemaname) || '.' || quote_ident(S.relname)) ||
       ', COALESCE(MAX(' ||quote_ident(C.attname)|| '), 1) ) FROM ' ||
       quote_ident(PGT.schemaname)|| '.'||quote_ident(T.relname)|| ';'
FROM pg_class AS S,
     pg_depend AS D,
     pg_class AS T,
     pg_attribute AS C,
     pg_tables AS PGT
WHERE S.relkind = 'S'
    AND S.oid = D.objid
    AND D.refobjid = T.oid
    AND D.refobjid = C.attrelid
    AND D.refobjsubid = C.attnum
    AND T.relname = PGT.tablename
ORDER BY S.relname;

After running this query, you will need to execute the results of the query. I typically copy and paste into Notepad. Then I find and replace "SELECT with SELECT and ;" with ;. I copy and paste into pgAdmin III and run the query. It resets all of the tables in the database. More "professional" instructions are provided at the link above.


I was getting the same error as the OP.

I had created some Django models, created a Postgres table based on the models, and added some rows to the Postgres table via Django Admin. Then I fiddled with some of the columns in the models (changing around ForeignKeys, etc.) but had forgotten to migrate the changes.

Running the migration commands solved my problem, which makes sense given the SQL answers above.

실제로 적용하지 않고 적용되는 변경 사항을 확인하려면 :
python manage.py makemigrations --dry-run --verbosity 3

이러한 변경 사항에 만족하면 다음을 실행하십시오.
python manage.py makemigrations

그런 다음 다음을 실행하십시오.
python manage.py migrate

참조 URL : https://stackoverflow.com/questions/11089850/integrityerror-duplicate-key-value-violates-unique-constraint-django-postgres

반응형