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