SilentSokolov
@SilentSokolov

Поведение ContentType?

models.py

class Tag(models.Model):<br>
    user = models.ForeignKey(User)<br>
    content_type = models.ForeignKey(ContentType)<br>
    object_id = models.PositiveIntegerField()<br>
    content_object = generic.GenericForeignKey('content_type', 'object_id')<br>


views.py

try:<br>
    obj = Tag.objects.get(user_id=user.id, content_type=obj_type, object_id=item_id)<br>
except ObjectDoesNotExist:<br>
    obj = Tag.objects.create(user_id=user.id, content_type=obj_type, object_id=item_id)<br>
....<br>
obj.save()<br>




Кусок кода ищет в базе запись и если находит, то обновляет, если нет — создает новую. Можно записать более кратко через get_or_create, но ни суть. Суть в том, что при нескольких итерациях с одинаковыми значениями, он не находит запись и создает ее заново, потом жалуется что get() возвращает два объекта. При чем момент создания второго — рандомный, можно на третьей итерации, может на сотой.



Версия Django 1.5, база MySQL, кеш отрублен. Как не бился (передавал разные значения голые цифры и объекты, вместо get юзал filter[0]), все равно при Н-ной итерации создает дубль-запись в базе :\



Куда копать?
  • Вопрос задан
  • 3058 просмотров
Решения вопроса 1
SilentSokolov
@SilentSokolov Автор вопроса
Разобрался и нашел виновника — мускул, а именно InnoDB (по умолчанию для всех созданных таблиц с версии 5.5.5), если использовать MyISAM, то все стает на свои места и работает корректно. Решение подойдет не всем… но хоть какое-то :(
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 4
inlanger
@inlanger
Django программист
А я думал мы одни такие. У нас такая же проблема, и не совсем ясно откуда она взялась. И пока мы ее не решили :(
Ответ написан
@alz
Попробуйте все-таки get_or_create + unique_together на поля, по которым делаете get_or_create
Ответ написан
Комментировать
Nikita
@Nikita
Вероятно, у вас есть проблемы с типом изоляции для innodb, вариант по-умолчанию не тот, который ожидает Django. Подробно о проблеме есть целый отдельный топик: habrahabr.ru/post/144161/
Ответ написан
Комментировать
homm
@homm

Видимо у вас все реквесты выполняются в транзакции (есть такая настройка в settings). И когда 2 реквеста приходят примерно в одно время, они открывают транзакцию каждый свою и смотрят в ней запись. Оба не находят. Разница между майисам и иннодб в том, что первый просто не поддерживает трнзакций.

Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы