Удаление большого Django QuerySets приводит к внутренней ошибке сервера Apache

Я пытаюсь удалить примерно 200 000 объектов (у всех есть несколько связанных объектов, всего около 2 000 000 объектов), используя:

DataRecord.objects.filter(order=self.order).delete()

Но я получаю внутреннюю ошибку сервера (примерно через 20 минут или около того), и ни один из объектов не удаляется. У меня установлено время ожидания Apache 3600 (1 час), чтобы дать достаточно времени для этой операции.

Есть ли более эффективный способ массового удаления очень большого количества объектов?

2 ответа

Похоже, что лучшим решением является использование необработанного запроса (см. https://docs.djangoproject.com/en/dev/topics/db/sql/), но pre_delete, post_delete сигналы не будут срабатывать.

случайная идея ORM: есть DataRecord.order колонка индексируется?

редактировать: распознавать, если столбец легко: посмотреть, если столбец установлен db_index свойство, то есть:

class DataRecord(models.Model):
    order = models.IntegerField(_("order"), **db_index=True**)

Индекс позволяет быстро находить данные, не читая всю таблицу. Это похоже на указатель в книге - когда вы хотите найти какое-то слово там, указатель поможет вам найти его, не читая всю книгу.

Найдите количество объектов, которые будут удалены, и разбейте удаление на кратные 1000 или около того в цикле for. Простой пример:

q = DataRecord.objects.filter(order=self.order)
cnt = q.count()
bucket = 1000
a, rem = divmod(cnt, bucket) 
i, j, k = 0, bucket, 0
while k<a:
    for obj in q[k*bucket: (k+1)*bucket + (k+1==a and rem)]:
        obj.delete()
    k+=1
Другие вопросы по тегам