Django数据库对象,通过任务循环很多内存

时间:2014-07-15 21:17:35

标签: python django sqlite

我试图遍历我的数据库(sqlite),并检查是否缺少1和Max_Value(其中Max_Value是当前最大的主键)之间的任何主键(整数值)。它们应该是并发的。

所以我有一个在数据库中运行的定期任务,目前该方法定义如下:

def checkMissing(maxValue, databaseObjects):
    missingValues = []
    for x in range(1, maxValue):
        if(len(missingValues) < 1000):
            if(not(databaseObjects.objects.filter(pk=x).exists())):
                print "Missing:" + str(x) + ", Current Size:" + str(len(missingValues))
                missingValues.append(x)
    return missingValues

大约有50万个项目,但是如果我在Windows中打开任务管理器,它需要的内存量每5分钟增加100,00 K.我做过len(失踪)&lt; 1000,以防止数据库找到太多的项目,但如果数据库没有错误,那么它将循环到最后导致大量的内存使用。

我已经阅读了Django网站上的QuerySet文章:

https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.exists

它确实说存在是一种更好的方式。但是,周期性函数仍然会崩溃并引发内存错误。

2 个答案:

答案 0 :(得分:3)

嗯,你可以这样做:

def check_missing(max_value, db_objects):

    set_of_pk_values = set( db_objects.objects.all().values_list('pk', flat=True) )

    set_one_to_max_value = set(xrange(1, max_value+1))

    return set_one_to_max_value.difference(set_of_pk_values)

答案 1 :(得分:1)

我可以问一下确保钥匙连续性的原因是什么?像Oracle这样的一些数据库甚至不能保证序列对象返回的密钥是递增的,让它们连续。

其次,您为x的每个值触发了一个选择查询。基本上,在该循环中,将会有一个SELECT ... FROM ... WHERE ID = ...查询将命中数据库。这是表现糟糕的原因。

更好的方法是获取按pk排序的所有记录并循环遍历它们并将它们存储在数组或其他内容中。然后处理数组以获取缺失值。

我还没有对这段代码进行过测试,但这就是我的目标

for x in databaseObject.objects.all():
    ids = ids + [x.id]

然后获得idsrange(maxValue)之间的差异并找出差异。

相关问题