8

APIから大量のデータを収集し、CSVにフォーマットし、圧縮して結果をストリーミングする必要があるpythonメソッドがあります。

私はグーグルをしてきましたが、見つけることができるすべての解決策は、一時ファイルに書き込むか、アーカイブ全体をメモリに保持する必要があります。

私はOOMをかなり急速に取得するので、メモリは間違いなくオプションではありません。一時ファイルへの書き込みには、それに関連する多くの問題があります (このボックスは、現時点ではログ用にディスクのみを使用する、ダウンロード開始までのリード タイムがはるかに長い、ファイルのクリーンアップの問題など)。それがただ厄介であるという事実は言うまでもありません。

次のようなことができるライブラリを探しています...

C = Compressor(outputstream)
C.BeginFile('Data.csv')
for D in Api.StreamResults():
    C.Write(D)
C.CloseFile()
C.Close()

つまり、データを書き込むときに出力ストリームを書き込むものです。

私は .Net と PHP でこれを行うことができましたが、Python でアプローチする方法がわかりません。

大まかに言えば、「大量の」データとは、最大 10 Gb の (生の平文) データを処理できる必要があることを意味します。これは、ビッグ データ システムのエクスポート/ダンプ プロセスの一部です。

4

2 に答える 2

10

gzip モジュールのドキュメントに記載されているように、ファイルのようなオブジェクトをGzipFileコンストラクターに渡すことができます。Python はダック型であるため、次のように独自のストリームを自由に実装できます。

import sys
from gzip import GzipFile

class MyStream(object):
    def write(self, data):
        #write to your stream...
        sys.stdout.write(data) #stdout, for example

gz= GzipFile( fileobj=MyStream(), mode='w'  )
gz.write("something")
于 2013-10-01T16:22:45.613 に答える
9

@goncaploppの答え​​は素晴らしいですが、gzipを外部で実行すると、より多くの並列処理を実現できます。大量のデータを収集しているため、余分な努力をする価値があるかもしれません。Windows 用の独自の圧縮ルーチンを見つける必要があります (いくつかの gzip 実装がありますが、7z のようなものも機能する可能性があります)。システムで他に最適化する必要があるものに応じて、gzip よりも多く圧縮する lz などを試すこともできます。

import subprocess as subp
import os

class GZipWriter(object):

    def __init__(self, filename):
        self.filename = filename
        self.fp = None

    def __enter__(self):
        self.fp = open(self.filename, 'wb')
        self.proc = subp.Popen(['gzip'], stdin=subp.PIPE, stdout=self.fp)
        return self

    def __exit__(self, type, value, traceback):
        self.close()
        if type:
            os.remove(self.filename)

    def close(self):
        if self.fp:
            self.fp.close()
            self.fp = None

    def write(self, data):
        self.proc.stdin.write(data)

with GZipWriter('sometempfile') as gz:
    for i in range(10):
        gz.write('a'*80+'\n')
于 2013-10-01T16:29:09.280 に答える