从REST端点高效读取并在Python中压缩结果

时间:2016-03-31 16:09:28

标签: python gzip

我有一个数据导出作业,它从REST端点读取数据,然后在写入S3之前将数据保存在临时压缩文件中。这适用于较小的有效载荷:

import gzip
import urllib2

# Fails when writing too much data at once    
def get_data(url, params, fileobj):
    request = urllib2.urlopen(url, params)
    event_data = request.read()
    with gzip.open(fileobj.name, 'wb') as f:
        f.write(event_data)

然而,随着数据量的增加,我得到了一个错误,似乎表明我一次写了太多数据:

File "/usr/lib64/python2.7/gzip.py", line 241, in write self.fileobj.write(self.compress.compress(data)) OverflowError: size does not fit in an int

我尝试修改代码以逐行读取REST端点并将每一行写入文件,但这非常慢,可能是因为端点未设置为处理该端点。

# Incredibly slow
def get_data(url, params, fileobj):
    request = urllib2.urlopen(url, params)
    with gzip.open(fileobj.name, 'wb') as f:
        for line in request:
            f.write(line)

是否有更有效的方法来实现这一点,例如通过一次读取整个有效负载,就像在第一个示例中一样,然后从现在驻留在内存中的数据中逐行读取?

1 个答案:

答案 0 :(得分:0)

原来这就是StringIO的用途。通过将我的有效负载转换为StringIO对象,我能够逐行读取并写入gzip压缩文件而没有任何错误。

from StringIO import StringIO

def get_data(url, params, fileobj):
    request = urllib2.urlopen(url, params)
    event_data = StringIO(request.read())
    with gzip.open(fileobj.name, 'wb') as f:
        for line in event_data:
            f.write(line)