40

Я слежу за question that I asked earlier, в котором я искал преобразования из тупого/плохо написанного запроса mysql в postgresql. Я считаю, что мне это удалось. В любом случае, я использую данные, которые были вручную перемещены из базы данных mysql в базу данных postgres. Я использую запрос, который выглядит так:Значение целочисленного ключа IntegrityError нарушает единственное ограничение - django/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) 
) 

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

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

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

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(

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

+1

В сторону: по законам Де Моргана ваше условие 'key [0]! = '_' Или ключ!= 'csrfmiddlewaretoken'' эквивалентно 'not (key [0] ==' _ 'и key ==' csrfmiddlewaretoken ')'. Легко видеть, что внутреннее условие никогда не выполняется, поэтому оно эквивалентно 'not (False)' или, другими словами, True. Но тогда зачем беспокоиться о 'if'? –

+0

'python manage.py sqlsequencereset | python manage.py dbshell' – Medorator

+0

Этот предыдущий ответ дает более подробную информацию и свет по теме: http://stackoverflow.com/questions/244243/how-to-reset-postgres-primary-key-sequence-when-it-falls -out-of-sync – RedSands

ответ

94

Это случилось со мной - выясняется, что вам нужно повторно синхронизировать свои первичные ключевые поля в Postgres. Ключ - это оператор SQL:

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

Вот и все! Я думал, что решил эту проблему, но, оказывается, я сброшу неправильное значение. –

+1

Я знаю о группе людей, у которых была эта проблема - я рад, что вы ее разрешили! –

+0

Я собирался спросить @HackingLife, если бы вы знали больше о том, почему это происходит ... получается для нас, потому что мы синхронизировали все данные из другой базы данных, скопировав их напрямую (что было зафодом, упомянутым в его ответе). Когда мы перестали это делать и начали напрямую использовать основную базу данных, последовательность первичных ключей не увеличивалась при добавлении новой модели, создавая эту ошибку. – AJP

2

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

Для всех, кто сталкивается с этим, попробуйте принуждая UPDATE с:

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

Если вы получите сообщение об ошибке, что вы не можете передать force_insert и force_update в то же время, вы, вероятно, передавая некоторые пользовательские аргументы неправильно , как и я.

+0

Это приятное решение в django. Из оболочки просто импортируйте свой класс модели (если вы не используете shell_plus), а затем выполните MyModelClass.objects.first(). Save (force_update = True) –

5

В дополнение к zapphods ответ:

В моем случае индексация была действительно неправильно, так как я удалил все миграции, а также базы данных, вероятно, в 10-15 раз при разработке, как я не был в стадии миграции что-нибудь.

я получаю IntegrityError на finished_product_template_finishedproduct_pkey

проиндексировать таблицу и перезапустить runserver:

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

enter image description here

А потом переиндексирован.

enter image description here

11

Это, кажется, известно, разница в поведении между MySQL и SQLite (они обновляют следующий доступный первичный ключ, даже при вставке объекта с явным идентификатором) движки и другие движки, такие как Postgres, Oracle , ... (они не).

There is a ticket describing the same issue. Несмотря на то, что он был закрыт как недопустимый, он дает понять, что есть команда управления Django для обновления следующего доступного ключа.

Для отображения SQL обновления всех следующих идентификаторов для применения MyApp:

python manage.py sqlsequencereset MyApp 

Для того, что оператор выполняется, вы можете предоставить его в качестве входных данных для команды dbshell управления. Для Баша, можно ввести:

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

Преимущества команд управления является то, что абстрагирует основной БД Серверным, поэтому он будет работать, даже если в дальнейшем переход на другой серверный.

1

У меня была та же проблема. Я имел существующую таблицу в моем «инвентаризации» приложении, и я хотел бы добавить новые записи в Джанго администраторе, и я получил эти сообщения:

Дубликат значения ключа нарушающего ограничения уникальности «inventory_part_pkey» ДЕТАЛИ: Ключ (part_id) = (1) уже существует.

Как упоминалось ранее запустить код ниже, чтобы получить генерировать команду SQL для сброса Ид-S:

python manage.py sqlsequencereset inventory 

В моем случае python manage.py sqlsequencereset MyApp | python manage.py dbshell не работал

  • Я скопировал сгенерированный оператор SQL.
  • Затем открыл pgAdmin для postgreSQL и открыл мой db.
  • Нажмите на значок 6. (Выполнение произвольных SQL-запросов)
  • Скопировано заявление о том, что было создано.

В моем случае это было:

НАЧАТЬ; SELECT setval (pg_get_serial_sequence ('"inventory_signup",' id '), coalesce (max ("id"), 1), max ("id") НЕ НЕВОЗМОЖНО) FROM "inventory_signup"; SELECT setval (pg_get_serial_sequence ('"inventory_supplier"', 'id'), coalesce (max ("id"), 1), max ("id") НЕ НЕВОЗМОЖНО) FROM "inventory_supplier"; COMMIT;

Выполнено с F5.

Это фиксировало все мои таблицы и, наконец, добавило новые записи в конец, не пытаясь добавить его в id = 1.

+0

Этот ответ просто спас мой день! – Gambit2007