Python(+ django)在简单脚本

时间:2015-08-27 22:36:10

标签: python django model garbage-collection

所以我在python中有这个脚本。 它使用django中的模型从数据库中获取一些(确切地说:很多)数据。

快速“总结”我想要实现的目标(可能不那么重要,所以你也可以通过查看代码来获得它):
有A型物体 对于每个A对象,存在B类型的相关对象(1到多个) 对于每个B对象,都有C类型的相关对象(1到多个) 对于每个C对象,有一个对我来说特别有趣的相关对象 - 我们称之为D(1对1关系)。

对于数据库中的每个A对象(不是很多),我需要获取与其相关的所有B对象以及与其相关的所有D对象,以创建A对象的摘要。每个摘要都是一个单独的工作表(我使用 openpyxl )。

我写的代码是有效的(意思是:它做了我想要它做的事情),但垃圾收集存在问题,所以进程被杀死了。我尝试过不使用预取,因为时间不是很重要,但它并没有真正帮助。

摘要代码:

a_objects = A.objects.all()
wb = Workbook()

for a_object in a_objects:
    ws = wb.create_sheet()
    ws.title = a.name
    summary_dictionary = {}
    << 1 >>
    b_objects = B.objects.filter(a_object=a_object)

    for b_object in b_objects:
        c_objects = C.objects.filter(b_object=b_object)
        for c_object in c_objects:
            # Here i put a value in dictionary, or alter it, 
            # depending on whether c_object.d_object has unique fields for current a_object
            # Key is a tuple of 3 floats (taken from d_object)
            # Value is array of 3 small integers (between 0 and 100) 

    summary_dictionary = sorted(summary_dictionary.items(), key=operator.itemgetter(0))

    for summary_item in summary_dictionary:
        ws.append([summary_item[0][0], summary_item[0][1], summary_item[0][2], summary_item[1][0], summary_item[1][1], summary_item[1][2], sum(summary_item[1])])

wb.save("someFile.xlsx")

虽然理论上整个xlsx文件可能很大 - 可能超过1GB,如果所有的d_objects值都是唯一的,我估计它甚至在脚本末尾都要低于100 MB。正在执行脚本时,系统中有大约650 MB的可用内存。

大约有80个A对象,脚本在6或7个之后被杀死。我使用“top”来监视内存使用情况并且没有注意到任何内存被释放,这很奇怪,因为,让我们说:第3个a_object有1000个与它相关的b_objects,每个b_object有30个与它相关的c_objects和
第4个a_object只有100个与它相关的b_objects,每个b_object只有2个与它相关的c_objects。

在&lt;&lt; 1&gt;&gt;之后应该释放大量内存。在第四次迭代中,对吗?
我的观点是,我认为这个程序的行为应该是,只要以下内容可以适合内存,它就会运行:
- 整个摘要
- 一组所有b_objects及其c_objects及其d_objects,用于数据库中的任何a_object。

我错过了什么?

1 个答案:

答案 0 :(得分:0)

尝试切换:

a_objects = A.objects.all()

为:

a_objects = A.objects.all().iterator()