IntegrityError重复键值违反唯一约束-django/postgres

IntegrityError重复键值违反唯一约束-django/postgres,django,postgresql,duplicates,unique-constraint,database-integrity,Django,Postgresql,Duplicates,Unique Constraint,Database Integrity,我正在跟进一个例子,在这个例子中,我试图寻求从一个愚蠢/写得很糟糕的mysql查询到postgresql的转换。我相信我成功了。无论如何,我使用的数据是手动从mysql数据库移动到postgres数据库的。我使用的查询如下所示: UPDATE krypdos_coderound cru set is_correct = case when t.kv_values1 = t.kv_values2 then True else False end

我正在跟进一个例子,在这个例子中,我试图寻求从一个愚蠢/写得很糟糕的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(

我已经检查了序列等等,它们似乎是有序的。在这一点上,我不确定该怎么办——我想这是django的事情,但我不确定。任何反馈都将不胜感激

如果您手动复制了数据库,您可能会运行到。

如果您手动复制了数据库,您可能会运行到。

这件事发生在我身上-您需要在Postgres中重新同步主键字段。关键是SQL语句:

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

这件事发生在我身上——事实证明你需要在Postgres中重新同步主键字段。关键是SQL语句:

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

我遇到这个错误是因为我以错误的方式向save方法传递了额外的参数

对于遇到此问题的任何人,请尝试使用以下命令强制更新:

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

如果您遇到一个无法同时传递
force\u insert
force\u update
的错误,您可能以错误的方式传递了一些自定义参数,就像我一样。

我遇到了这个错误,因为我以错误的方式向save方法传递了额外的参数

对于遇到此问题的任何人,请尝试使用以下命令强制更新:

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

如果您得到一个无法同时传递
force\u insert
force\u update
的错误,您可能以错误的方式传递了一些自定义参数,就像我所做的那样。

除了zapphods回答:

在我的例子中,索引确实是不正确的,因为我已经删除了所有迁移,而且数据库在开发时可能会删除10-15次,因为我没有迁移任何东西

我在
finished\u product\u template\u finishedproduct\u pkey

重新索引表并重新启动runserver: 我使用的是pgadmin3,对于不正确的索引和抛出重复的键错误,我导航到
约束
并重新编制索引

然后重新编制索引


除了zapphods回答:

在我的例子中,索引确实是不正确的,因为我已经删除了所有迁移,而且数据库在开发时可能会删除10-15次,因为我没有迁移任何东西

我在
finished\u product\u template\u finishedproduct\u pkey

重新索引表并重新启动runserver: 我使用的是pgadmin3,对于不正确的索引和抛出重复的键错误,我导航到
约束
并重新编制索引

然后重新编制索引


MySQL和SQLite(即使插入具有显式id的对象,它们也会更新下一个可用主键)后端和其他后端(如Postgres、Oracle等)之间的行为差异似乎是众所周知的。。。(他们没有)

。即使它被关闭为无效,它也会提示有一个Django管理命令来更新下一个可用密钥

要显示更新应用程序MyApp的所有下一个ID的SQL语句,请执行以下操作:

为了执行该语句,可以将其作为dbshell管理命令的输入。对于bash,您可以键入:

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

管理命令的优点是抽象了底层数据库后端,因此即使以后迁移到不同的后端,它也能工作。

MySQL和SQLite(即使插入具有显式id的对象,它们也会更新下一个可用主键)后端之间的行为差异似乎是已知的,以及其他后端,如Postgres、Oracle。。。(他们没有)

。即使它被关闭为无效,它也会提示有一个Django管理命令来更新下一个可用密钥

要显示更新应用程序MyApp的所有下一个ID的SQL语句,请执行以下操作:

为了执行该语句,可以将其作为dbshell管理命令的输入。对于bash,您可以键入:

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

管理命令的优点是可以抽象出底层数据库后端,因此即使以后迁移到其他后端,它也可以工作。

我的“库存”应用程序中有一个现有表,我想在Django admin中添加新记录,但出现以下错误:

重复的键值违反唯一约束“库存\零件\ pkey” 详细信息:密钥(part_id)=(1)已存在

如前所述,我运行下面的代码以获取重置id-s的SQL命令:

python manage.py sqlsequencereset inventory

python manage.py sqlsequencereset inventory | python manage.py dbshell
管道连接到shell不起作用

  • 所以我复制了生成的原始SQL命令
  • 然后打开pgAdmin3
    https://www.pgadmin.org
    用于postgreSQL并打开了我的数据库
  • 点击6。图标(执行任意SQL查询)
  • 复制了生成的语句
在我的例子中,原始SQL命令是:

BEGIN;
SELECT setval(pg_get_serial_sequence('"inventory_signup"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "inventory_signup";
SELECT setval(pg_get_serial_sequence('"inventory_supplier"','id'), coalesce(max("id"), 1), max("id") IS NOT null) FROM "inventory_supplier";
COMMIT;
用F5执行它


这修复了所有问题。

我的“库存”应用程序中有一个现有表,我想在Django admin中添加新记录,但出现以下错误: