1

私は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()

私の最初の推測では、なんらかの形のメモリ リークがあったので、これを修正するために、メモリが適切に収集されることを期待して、2 つの大きな配列に del ステートメントを追加しました。今回は、わずかに良い出力が得られました (わずかに良いということは、db 列のペアに対してより多くの出力ファイルが作成されたことを意味します)。しかし、10 番目または 11 番目の列のペアの後、私のプログラムは再び「強制終了」されました。誰かがここで何が間違っているのか教えてもらえますか. これを行うためのより良い方法はありますか?どんな助けでも大歓迎です。

PS: 私は何度もループしているので、これはかなり非効率的な実装であることを知っていますが、概念実証のために迅速で汚いものが必要でした.

4

1 に答える 1

1

ここでの問題は、すべてを選択し、SQLクエリで必要なものを選択する必要があるときにアプリケーションコードでフィルタリングすることだと思います。次のようにSQLクエリで必要なものを選択した場合:

varlistのlistvarの場合:listvar[1]がnullではなくlistvar[2]がnullではないlistvar[0]からlistvar[1]、listvar[2]を選択します

# 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
于 2012-10-11T07:44:50.113 に答える