Использование QuerySet.update () против ModelInstance.save () в Django - PullRequest
4 голосов
/ 23 декабря 2010

Мне любопытно, что другие думают об этой проблеме ...

В последние несколько дней я ходил взад и вперед по поводу использования QuerySet.update() против ModelInstance.save(). Очевидно, что если будет изменено много полей, я бы использовал save(), но для обновления пары полей я думаю, что лучше использовать QuerySet.update(). Преимущество использования QuerySet.update() состоит в том, что вы можете одновременно запускать несколько потоков update() на разных полях одного и того же объекта, и у вас не будет проблем с расой. Метод save() по умолчанию сохраняет все поля, поэтому параллельная save() из двух потоков будет проблематичной.

Итак, проблема в том, что если у вас перегружены пользовательские save() методы. Лучшее, что я могу придумать, это абстрагировать что-либо в пользовательском методе save() в отдельные методы обновления, которые на самом деле используют QuerySet.update() для установки пары полей в модели. Кто-нибудь использовал этот шаблон?

Что немного раздражает, так это то, что в Django Admin даже при редактировании в режиме списка изменений, когда вы редактируете только одно поле, сохраняется вся модель. По сути, это означает, что если у кого-то открыт список изменений в его / ее браузере, а в некоторых других местах системы поле обновляется, это обновленное значение будет выброшено, когда этот пользователь сохранит изменения из списка изменений. Есть ли решение этой проблемы?

Мысли

Спасибо.

Ответы [ 2 ]

8 голосов
/ 23 декабря 2010

Основная причина использования QuerySet.update() заключается в том, что вы можете обновить несколько объектов одним запросом к базе данных, в то время как каждый вызов метода save объекта будет попадать в базу данных!

Еще один момент, о котором стоит упомянуть, это то, что сигналы pre_save & post_save django отправляются только при вызове save -метода объекта, но не при QuerySet.update().

Что касается конфликтных проблем, которые вы описываете, я думаю, что будет также раздражать, если вы нажмете «сохранить», а затем вы должны обнаружить, что впоследствии некоторые значения такие же, как и при их изменении, но некоторые, которые вы оставили без изменений, изменилось?!? Конечно, вам нужно изменить save_model админа или метод объекта save на поведение, которое вы предлагаете.

3 голосов
/ 24 декабря 2010

Проблема, которую вы описали в Django Admin, заключается в обновлении экземпляра модели с использованием устаревшей копии. Это легко исправить, добавив номер версии к каждому экземпляру модели и увеличивая номер при каждом обновлении. Затем в методе save модели просто убедитесь, что то, что вы сохраняете, не отстает от того, что уже есть в базе данных.

Я хочу убедиться, что при параллельной записи в один и тот же объект каждая запись обновляет разные поля, они не перезаписывают значения друг друга.

В зависимости от применения, это может быть или не быть разумной вещью. Сохранение всей модели, даже если обновлено только одно поле, часто позволяет избежать нарушения целостности данных. Думая о следующем примере о маршруте путешествия трех ног. Предположим, есть экземпляр трех полей, представляющих три ветви, и три поля: SF->LA, LA->DC, DC->NY. Теперь, если одним обновлением является обновление первых двух ветвей до SF->SD, SD->DC, а другим обновлением является обновление последних двух ветвей до LA->SJ, SJ->NY, и если вы позволите обоим произойти с update вместо сохранения полного экземпляра модели вы получите ломаный маршрут SF->SD, LA->SJ, SJ->NY.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...