我是python的新手,正面临着似乎是内存泄漏错误的问题。
我编写了一个简单的脚本,该脚本试图从postgres数据库中获取多个列,然后对这些列执行简单的减法运算并将结果存储在正在写入文件的临时变量中。我需要在数据库中的多对列上执行此操作,并且我使用列表列表来存储不同的列名称。
我遍历此列表的各个元素,直到列表用完为止。当我获得前几列对的有效结果(有效时,我的意思是输出文件包含期望值)时,程序在执行之间突然被“杀死”。代码如下:
varList = [ ['table1', 'col1', 'col2'],
['table1', 'col3', 'col4'],
['table2', 'col1', 'col2'],
# ..
# and many more such lines
# ..
['table2', 'col3', 'col4']]
try:
conn = psycopg2.connect(database='somename', user='someuser', password='somepasswd')
c = conn.cursor()
for listVar in varList:
c.execute("SELECT %s FROM %s" %(listVar[1], listVar[0]))
rowsList1 = c.fetchall();
c.execute("SELECT %s FROM %s" %(listVar[2], listVar[0]))
rowsList2 = c.fetchall();
outfile = file('%s__%s' %(listVar[1], listVar[2]), 'w')
for i in range(0, len(rowsList1)):
if rowsList1[i][0] == None or rowsList2[i][0] == None:
timeDiff = -1
else:
timestamp1 = time.mktime(rowsList1[i][0].timetuple())
timestamp2 = time.mktime(rowsList2[i][0].timetuple())
timeDiff = timestamp2 - timestamp1
outfile.write(str(timeDiff) + '\n')
outfile.close();
del rowsList1, rowsList2
#numpy.savetxt('output.dat', column_stack(rows))
except psycopg2.DatabaseError, e:
print 'Error %s' % e
sys.exit(1)
finally:
if conn:
conn.close()
我最初的猜测是存在某种形式的内存泄漏,为了解决此问题,我在两个大型数组上添加了del语句,希望可以正确收集内存。这次,我得到了更好的输出(通过更好的意思是为数据库列对创建了更多的输出文件)。
但是,在第10列或第11列对之后,我的程序再次被“杀死”。有人可以告诉我这里有什么问题吗。有没有更好的方法可以做到这一点?
任何帮助表示赞赏。
PS:我知道这是一个效率很低的实现,因为我要循环很多次,但是我需要快速而肮脏的东西来证明概念。
最佳答案
我认为这里的问题是,您应该选择所有内容,然后在应使用sql查询选择所需内容时在应用程序代码中对其进行过滤。如果您在SQL查询中选择所需的内容,如下所示:
对于varlist中的listvar:
从listvar [0]中选择listvar [1],listvar [2],其中listvar [1]不为null,listvar [2]不为null
# then...
timeDiff = {}
for row in rows:
timestamp1 = time.mktime(row[0].timetuple())
timestamp2 = time.mktime(row[0].timetuple())
timeDiff[identifier] = timestamp2 - timestamp1 #still need to assoc timediff with row... maybe you need to query a unique identifyer also?
#and possibly a separate... (this may not be necessary depending on your application code. do you really need -1's for irrelevant data or can you just return the important data?)
select listvar[1], listvar[2] from listvar[0] where listvar[1] is null or listvar[2] is null
for row in rows:
timeDiff[identifier] = -1 # or None