我有一个数据导出作业,它从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)
是否有更有效的方法来实现这一点,例如通过一次读取整个有效负载,就像在第一个示例中一样,然后从现在驻留在内存中的数据中逐行读取?
答案 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)