Django 1.10删除大型级联querySet

时间:2017-07-12 00:42:54

标签: python django django-models

我试图从大型查询集中删除所有对象。这是我的models.py

from __future__ import unicode_literals
from django.contrib.auth.models import User
from django.db import models


class Fund(models.Model):

    name = models.CharField(max_length=255, blank=False, null=False)
    start_date = models.DateField(default=None, blank=False, null=False)

    def __unicode__(self):
        return self.name


class FundData(models.Model):

    fund = models.ForeignKey(Fund, on_delete=models.CASCADE)
    date = models.DateField(default=None, blank=False, null=False)
    value = models.FloatField(default=None, blank=True, null=True)

    def __unicode__(self):
        return "{} --- Data: {} --- Value: {} ".format(str(self.fund), str(self.date), str(self.value))

但是当我尝试删除所有记录时,查询需要花费太多时间,并且mysql正在超时。

Fund.objects.all().delete()
  • 在视图中管理此操作的最佳方法是什么?
  • 有一种方法可以从终端调用django命令吗?

2 个答案:

答案 0 :(得分:1)

首先,您可以通过编辑settings.py

来更改MySQL的超时时间
DATABASES = {
    'default': {
        ...
        OPTIONS = {
            'connect_timeout': 5, # your timeout time
        }
        ...
    }
}

.delete()可能缓慢的原因是:

  1. Django必须正确地确保级联删除功能。它必须寻找模型的外键
  2. Django必须以某种方式处理模型的保存前和保存后信号
  3. 如果您确定您的模型没有级联删除或任何要处理的信号,您可以尝试使用私有_raw_delete,如下所示:

    queryset._raw_delete(queryset.db)
    

    您可以在here

    上找到更多详细信息

答案 1 :(得分:0)

最后我得到了一个简单的解决方案,删除所有级联对象,分解宏删除操作,逐个删除基金对象。因为它是一个非常长的操作(对于数千个对象,每个对象大约1秒)我将它分配给芹菜工人。我认为缓慢但安全,如果有人得到更好的解决方案,请告诉我!

@shared_task
def reset_funds():
    for fund in Fund.objects.all():
        print "Delete Fund: {}".format(fund.name)
        fund.delete()
    return "All Funds Deleted!"