Блокирует ли метод Model.update в django таблицу перед сохранением экземпляров?
У меня есть сценарий, в котором мне нужно скопировать значения одного столбца в другой столбец. Я пытаюсь сделать
Model.objects.select_related('vcsdata').all().update(charging_status_v2=F('charging_status'))
Создает ли использование F-выражения вместе с обновлением для копирования значений какое-либо время простоя? Блокирует ли оно таблицу во время выполнения операции?
связанный_вопрос_для_большего_контекста
Короткий ответ:
Нет, не имеет.
Единственное, что делает Django в процессе обновления (независимо от того, используете вы выражение F или нет), это сохраняет предыдущее состояние вашей записи (записей), чтобы в случае, если что-то пойдет не так, можно было откатиться к предыдущему состоянию.
def update(self, **kwargs):
"""
Update all elements in the current QuerySet, setting all the given
fields to the appropriate values.
"""
self._not_support_combined_queries('update')
assert not self.query.is_sliced, \
"Cannot update a query once a slice has been taken."
self._for_write = True
query = self.query.chain(sql.UpdateQuery)
query.add_update_values(kwargs)
# Clear any annotations so that they won't be present in subqueries.
query.annotations = {}
with transaction.mark_for_rollback_on_error(using=self.db):
rows = query.get_compiler(self.db).execute_sql(CURSOR)
self._result_cache = None
return rows
В основном, в строке with transaction.mark_for_rollback_on_error(using=self.db) сохраняется предыдущее состояние записи, но не происходит блокировки таблицы или каких-либо частичных блокировок.
Например, если у вас есть два одновременных обновления в одно и то же время, (предположим, что одно из них займет намного больше времени, чем другое, а также более медленное обновление попадет в вашу базу данных раньше, чем более быстрое), то более быстрое обновление попадет в вашу базу данных независимо от более медленного и выполнит операцию. Затем более медленный выполнит какую-то другую операцию над вашей таблицей (этого примера достаточно для доказательства того, что обновление не блокирует вашу таблицу).
Также обратите внимание, что вызов update для обновления нескольких объектов (если это выполнимо) является наиболее эффективным способом обновления нескольких объектов, насколько я знаю (по сравнению с вызовом save на каждом экземпляре или массовым обновлением).