IntegrityError с отношениями Django M2M
-
28-09-2019 - |
Вопрос
У меня есть относительно простое приложение Django, с довольно тяжелым использованием, которое отвечает за довольно некоторое параллелизм в операциях БД.
У меня есть модель пост с M2M в модель тега.
Одна строка в моем коде, p.add(t)
неоднократно вызывает исключения MySQL (где p
это пост экземпляра и t
это экземпляр тега.)
IntegrityError: (1062, "Duplicate entry '329051-1827414' for key 'post_id'")
Когда это поднят, я могу вручную запустить это p.add(t)
Успешно, поэтому ему нужно сделать с каким-то своеобразным состоянием, что БД / приложение во время обычного выполнения. Это происходит примерно раз каждые 1000 попыток добавления тегов, без каких-либо шаблонов, которые я могу обнаружить (то есть оба количества в паре примера «329051-1827414».
А. CHECK TABLE
В MySQL на соответствующей таблице показано, что они все, казалось бы, хорошо.
Есть идеи?
Решение
Обычно вы видите такие ошибки, когда пытаясь добавить в промежуточную таблицу, если ряд добавляют дубликаты уникальных ограничений для FK. Я предполагаю, что в примере вы предоставили «329051» - это идентификатор сообщения и «1827414» - это идентификатор тега.
Обычно в Django вы можете называть метод ADD () несколько раз, чтобы добавить тот же экземпляр, а Django заботится обо всем для вас. Я предполагаю, что модель Model Manager поддерживает некоторое состояние, чтобы помочь ему определить, если каждое добавление () представляет собой новую или существующую строку, и если ряд, кажется, новая, она пытается вставить.
Что само по себе не объясняет, почему вы получаете ошибку. Вы упоминаете, что «несет ответственность за довольно некоторое параллелизм в операциях БД». Не зная, что это значит, я предполагаю, что вы можете получить состояние гонки, где несколько потоков / процессов пытаются добавить тот же новый тег примерно в то же время, и оба пытаются вставки.
Другие советы
Я думаю, что я вижу подобную проблему в моем приложении - если я отправлю два идентичных запроса, чтобы добавить отношение M2M (например, тег в моем случае), я получаю эту ошибку, потому что таблица M2M имеет уникальное ограничение (пользователь, ярлык). Я предполагаю, что сервер обрабатывает функции .add в то же время.
if not already in database:
# Both invocations reach here because the next line takes some time to process.
create m2m row
Я не знаю, как это можно исправить.