2016-08-18 7 views
0

私は1.6GBのpythonプロセスで使用できるようになっています。私はデータがデータベースから来ている大きなCSVファイルを書いています。問題は次のとおりです。ファイルが書き込まれた後、メモリ(> 1.5GB)がすぐに解放されず、コードの次のビットにエラーが発生します(割り当てに十分なメモリが見つからないためメモリが割り当てられません)。Pythonでcsv.writerを使用した後、どのようにメモリを解放できますか?

メモリを解放するのに役立つ機能はありますか? または、より良い方法がありますか?

これは、私がファイルを書き込むために使用しているスクリプトですメモリの問題に対処するために、チャンクで書いている:

size_to_read = 20000 
sqlData = rs_cursor.fetchmany(size_to_read) 

c = csv.writer(open(fname_location, "wb")) 
c.writerow(headers) 

print("- Generating file %s ..." % out_fname) 

while sqlData: 
    for row in sqlData: 
    c.writerow(row) 
    sqlData = rs_cursor.fetchmany(size_to_read) 
+0

最後の行の後にエラーが出るコードはありますか?それともエラーの最後の行ですか? – Adam

+0

いいえ、メモリが不足している行数が少なく、この行にエラーがあります:file_obs = int(subprocess.check_output(["cat%s /%s | wc -l"%(locationToUpload、filename)]、 shell = True)) – ebertbm

+0

私は間違っているかもしれませんが、最後の行では 'sqlData = rs_cursor.fetchmany(size_to_read)'ですか?あなたがちょうどファイル(あなたが閉じていない)に書いたものすべてをもう一度ロードしますか? – roganjosh

答えて

1

私はこの問題を考えていますが、ファイルを閉じないことです。これを撃つ。 withを使用することにより

size_to_read = 20000 
sqlData = rs_cursor.fetchmany(size_to_read) 

with open(fname_location, "wb")) as f: 
    c = csv.writer(f) 
    c.writerow(headers) 

print("- Generating file %s ..." % out_fname) 

while sqlData: 
    with open(fname_location, "a") as f: # "a" means to append 
     c = csv.writer(f) 
     for row in sqlData: 
      c.writerow(row) 
    sqlData = rs_cursor.fetchmany(size_to_read) 

あなたは自動的にファイルを閉じて、メモリを解放します。明示的に私はデータを持っていないので、複製すること

while sqlData: 
    with open(fname_location, "wb") as f: 
     c = csv.writer(f) 
     c.writerows(sqlData) # .writerows 
    sqlData = rs_cursor.fetchmany(size_to_read) 

は、ハード...あなたがそう等によりループを避けることができると信じて:(

EDITまたc.close()

を呼び出すする必要がなくなります

これは本当に答えではありませんが、memory_profilerの行を評価して、多くのメモリを使用している場所を確認してください。ここでは210

EDIT 2

は、あなたのメモリ使用量を低く維持するために発電機を使用した例です。 http://code.activestate.com/recipes/137270-use-generators-for-fetching-large-db-record-sets/

経由

def results_iter(cursor, n=10000): 
    while True: 
     results = cursor.fetchmany(n) 
     if not results: 
      break 
     for result in results: 
      yield result 

with open('file.csv') as f: 
    c = csv.writer(f) 
    for result in results_iter(rs_cursor, size_to_read) 
     c.writerow(result) 

これのいずれかが、私たちに知らせて動作する場合は!

+0

ええ、私はデータがどのように見えるかわからないと言っているように私は本当に分かりません。あるいは、彼が 'size_to_read'によって何を意味するのか。しかし、投票に感謝! – Adam

+0

私は、その間のイベント操作(つまり、より多くのデータを取得)で繰り返し開くと、大量のメモリを消費し、アプリケーションをクラッシュさせると思います。しかし、はい、ループの範囲は混乱しています。あなたが考えていない問題を人々が選ぶかもしれないので、間違ったものを出版することは価値があります。 – Adam

+0

基本的には、ループを使用していないと、ファイルを書き込んでいる間にシステムがメモリ不足になるためです。だから、私が持っていたアイデアは、すべてが完了したらデータのチャンクを書くことです。 size_to_readは、プロセスが各ループに対して書き込む行数です。 – ebertbm

関連する問題