5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Djangoで取得件数の多いSQLの結果をcsvとしてエクスポートさせる

Posted at

SQLの実行結果をCSVとしてエクスポートさせることは多々あるんですが、
その件数結果が多すぎてタイムアウトが発生したとか、メモリを使いすぎてwebサーバが爆発:boom:した……ということも稀にあったりします。
ので、少しずつ取得しつつ結果をcsvとして出力する方法を備忘録も兼ねて。

準備するもの!

class Echo(object):
    def write(self, value):
        return value

def yield_query(query):
    filter_id = 0

    while True:
        rows = list(query.filter(id__gt=filter_id).order_by('id')[:1000])

        if len(rows) == 0:
            break

        for row in rows:
            yield row

        filter_id = rows[-1].id

def stream_csv_response(rows):
    writer = csv.writer(Echo())

    response = StreamingHttpResponse(
        (writer.writerow(row) for row in rows),
        content_type="text/csv"
    )

    response['Content-Disposition'] = 'attachment; filename="big.csv"'

    return response
  • yield_queryは、渡されたqueryを少しずつ実行していく関数です。
  • stream_csv_responseは、yield_queryの実行結果を引数rowsで受け取り、Djangoのresponseを返してあげる関数です。

呼び方!

# 適当なModelを用意
test_query = Test.objects

# yieldを返すobjectを取得
yield_rows = yield_query(test_query) 

# レスポンスの返却
return stream_csv_response(yield_rows)    

ね、簡単でしょ?

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?