2016-08-10 17 views
0

データベースからcsvファイルに大量のデータ(> 1GB)を抽出する必要があります。私はこのスクリプトを使用しています:Pythonを使用して大きなcsvファイルを書き込むにはどうすればよいですか?

rs_cursor = rs_db.cursor() 
rs_cursor.execute("""SELECT %(sql_fields)s 
        FROM table1""" % {"sql_fields": sql_fields}) 
sqlData = rs_cursor.fetchall() 
rs_cursor.close() 

c = csv.writer(open(filename, "wb")) 
c.writerow(headers) 
for row in sqlData: 
    c.writerow(row) 

システムにメモリが不足しているファイルを書き込むときに問題が発生します。この場合、大規模なCSVファイルを作成するための他の効率的な方法はありますか?

+1

問題はおそらく、sqlData' 'ではなく、このデータをファイルに書き込むという事実です。このデータはどこから来たのですか?あなたはそれを支配していますか?そうしたら、それを塊で、またはジェネレーターとして読むことに目を向けるべきです。 – DeepSpace

+0

どのようにSQLデータを取得していますか?そのコードを私たちに見せてもらえますか? – drsnark

+0

私はsqlDataのコードのビットを追加しました。データは大規模なテーブルから来ています。 – ebertbm

答えて

2

psycopg2size引数を受け入れfetchmany方法を有しています。これを使用して、データベースから特定の行数を読み込みます。実行時とメモリ使用のバランスをとるために、値をnで期限切れにすることができます。

fetchmanyドキュメント:http://initd.org/psycopg/docs/cursor.html#cursor.fetchmany

rs_cursor = rs_db.cursor() 
    rs_cursor.execute("""SELECT %(sql_fields)s 
         FROM table1""" % {"sql_fields": sql_fields}) 
    c = csv.writer(open(filename, "wb")) 
    c.writerow(headers) 

    n = 100 
    sqlData = rs_cursor.fetchmany(n) 

    while sqlData: 
     for row in sqlData: 
      c.writerow(row) 
     sqlData = rs_cursor.fetchmany(n) 

    rs_cursor.close() 


また、コードを少し単純化する発電機でこれをラップすることができます:

def get_n_rows_from_table(n): 
    rs_cursor = rs_db.cursor() 
    rs_cursor.execute("""SELECT %(sql_fields)s 
          FROM table1""" % {"sql_fields": sql_fields}) 
    sqlData = rs_cursor.fetchmany(n) 

    while sqlData: 
     yield sqlData 
     sqlData = rs_cursor.fetchmany(n) 
    rs_cursor.close() 

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

for row in get_n_rows_from_table(100): 
    c.writerow(row) 
0

fetchone()を試しましたか? (OPが使用)

rs_cursor = rs_db.cursor() 
rs_cursor.execute("""SELECT %(sql_fields)s 
        FROM table1""" % {"sql_fields": sql_fields}) 

c = csv.writer(open(filename, "wb")) 
c.writerow(headers) 
row = rs_cursor.fetchone() 
while row: 
    c.writerow(row) 
    row = rs_cursor.fetchone() 

rs_cursor.close() 
+0

このアプローチはうまくいくが、データベースI/Oが遅いプロセスになる傾向があるため、非常に遅い可能性があります。 – DeepSpace

+0

あなたは 'fetchmany'を使って私の答えを見ることができます。 – DeepSpace

関連する問題