2014-01-15 3 views
1

Я использовал метод get_or_create с MongoEngine в приложении Django. Сегодня я заметил, что было несколько повторяющихся записей. Я наткнулся на это в Справочнике API MongoEngine для get_or_create:MongoEngine get_or_create Альтернативы

Для этого требуются две отдельные операции, и поэтому существует условие гонки. Поскольку в mongoDB нет транзакций, следует исследовать другие подходы, чтобы вы случайно не дублировали данные при использовании этого метода. Это в настоящее время планируется быть удалены до 1,0

Должен ли я использовать что-то вроде этого ?:

from models import Post 
post = Post(name='hello') 
try: 
    Posts.objects.get(name=post.name) 
    print "exists" 
except: 
    post.save() 
    print "saved" 

Будет ли это решить мою проблему? Есть ли лучший способ?

+0

Ваше предложение не решит проблему. Предположим, что у вас есть два экземпляра («потоки») вашей программы. Оба запускаются полностью синхронно. Таким образом, оба потока выполняют проверку существования в одно и то же время, и пока не существует объекта. Затем они продолжаются, и оба сохраняют → дубликат. – sk1p

ответ

3

Для выполнения upsert используйте следующий синтаксис:

Posts.objects(name="hello").update(set__X=Y, upsert=True) 

Это добавит пост с названием «привет», и где X = Y, если она уже не существует, в противном случае он будет обновлять существующий после установки X = Y.

+1

. Проблема с этой заменой заключается в том, что она не возвращается. 1) «Я вставлял или обновлял?» 2) какой идентификатор нового/обновленного объекта (ов)? См. Http://stackoverflow.com/questions/22176934/how-do-i-tell-if-i-inserted-during-upsert-in-mongoengine –

+0

Что мне не нравится в методе обновления, так это то, что вы не можете просто передайте ему простой словарь, чтобы указать свойства обновления. Перед каждой клавишей необходимо добавить «set__». –

Смежные вопросы