Учитывая список пар ключ-значение, есть несколько способов использовать их для запуска ОБНОВЛЕНИЯ в SQL:
Просто много запросов
UPDATE app_model SET column_a = %s WHERE id = %s
UPDATE app_model SET column_a = %s WHERE id = %s
UPDATE app_model SET column_a = %s WHERE id = %s
UPDATE app_model SET column_a = %s WHERE id = %s
Это легкодля представления в Django:
for key, value in updates:
Model.objects.filter(id=key).update(column_a=value)
Один запрос с кейсами
UPDATE app_model SET column_a = CASE
WHEN id = %s THEN %s
WHEN id = %s THEN %s
WHEN id = %s THEN %s
WHEN id = %s THEN %s
...
WHERE id IN (%s, %s, %s, %s, ...)
Предполагается, что это будет быстрее, потому что база данных может найти все строки более эффективно.В конечном итоге запрос будет очень длинным, и я бы предложил использовать этот подход с пакетами (скажем, 100 или 1000 строк, проведите эксперименты и посмотрите, что произойдет).
В Django вы можете сделать это либо черезORM :
Model.objects.filter(id__in=ids).update(
column_a=Case(
When(id=..., then=Value(...)),
When(id=..., then=Value(...)),
When(id=..., then=Value(...)),
When(id=..., then=Value(...)),
When(id=..., then=Value(...)),
...
)
)
или через сторонний пакет django-bulk-update , который делает похожую вещь с более приятным API.
Один запрос с SELECT FROM
Примечание. Это специфично для PostgreSQL.Другие базы данных могут предлагать другие аналогичные расширения SQL.
Если вы можете создать таблицу data
, содержащую все пары (key, value)
для обновления, то у вас хорошее место для элегантного одиночного-запрос:
UPDATE app_model
SET column_a = data.value
FROM data
WHERE app_model.id = data.key;
Вместо таблицы вы также можете заменить подзапрос, если это проще.
В любом случае, я не видел способа построить UPDATE FROM
запросов с использованием Django ORM пока нет, поэтому, насколько я могу судить, для этого требуется перейти на необработанный SQL.