从 REST 端点高效读取并将结果压缩到 Python

Efficiently read from REST endpoint and compress result in Python

我有一个数据导出作业,它从 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)

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

原来这就是 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)