Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将大文件写入blob存储并耗尽内存_Python_Google App Engine - Fatal编程技术网

Python 将大文件写入blob存储并耗尽内存

Python 将大文件写入blob存储并耗尽内存,python,google-app-engine,Python,Google App Engine,我正在使用实验性的blobstore文件API编写一个包含一些事件数据的CSV文件。有很多数据,所以我正在批量写入。我的代码在后台运行,所以我有很多时间,但我的内存不足,我不明白为什么 代码如下: from __future__ import with_statement from google.appengine.api import files q = Event.all() events = q.fetch(50) while events: with files.open(b

我正在使用实验性的blobstore文件API编写一个包含一些事件数据的CSV文件。有很多数据,所以我正在批量写入。我的代码在后台运行,所以我有很多时间,但我的内存不足,我不明白为什么

代码如下:

from __future__ import with_statement
from google.appengine.api import files

q = Event.all()

events = q.fetch(50)
while events:
    with files.open(blobname, 'a') as f:
        buf = StringIO()

        for event in events:
            buf.write(event.id)
            buf.write(',')
            buf.write(`event.logged`)
            buf.write(',')
            buf.write(event.type)
            buf.write(',')
            buf.write(event.timestamp)
            buf.write(',')

            needAmpersand = False
            for prop in event.dynamic_properties():
                if needAmpersand:
                    buf.write('&')
                needAmpersand = True
                buf.write(prop + '=' + str(getattr(event, prop)))
            buf.write('\n')

        f.write(buf.getvalue())
        buf.close()

    events = q.fetch(50)

files.finalize(blobname)
这段代码使while事件循环大约20次,然后进程在使用了超过140 mb的内存后中止。事件是特定于此应用程序的数据库模型。事件基本上是远程机器上发生的事件的记录,稍后这些事件将由map reduce操作处理以生成统计数据,现在我只想下载它们。我们的数据库中有1000个事件中的100个(稍后我们也将切换到以不同的方式存储它们,但目前仅此而已)

我注意到with
f.open
导致每次完成with子句时调用
f.close
,因为
f.close()
f

这段代码的一个早期实例只是在写入“StringIO”的每个元素上调用了f.write(..)。这个早期版本的内存耗尽速度快得多,但在其他方面表现类似。这段代码仍然有一些地方导致内存泄漏

帮忙

更新
我刚刚尝试注释掉f.write(buf.getvalue()),虽然它显然没有创建包含任何内容的blobstore项,但它最终完成了对所有事件实体的处理。我是否遗漏了某些内容,或者f.write()是否泄漏内存或缓冲所有内容直到finalize()?

当调用
f.write(buf.getvalue())
时,您要求
StringIO
将其自身转换为单个内存对象并传递该对象。那会很贵的

尝试
buf.seek(0)
,它将倒回流的开头,只需传递
f.write(buf)
StringIO
是一个类似文件的对象,
f.write
应该能够以流的形式读取它


看看,从文档或代码中不清楚
文件\u服务\u pb.AppendRequest
是否可以处理StringIO。试试看。

什么是
事件
?一个AppEngine对象?原始版本做了什么?不知道它做了什么就知道它“呕吐”是没有帮助的。谢谢。我对问题进行了编辑,以提供更清晰的信息。有用的观察结果,我将加以利用。但是,
buf.getvalue()
可能需要临时复制字符串,我同意这是低效的,但它不应该泄漏。它使它在内存耗尽之前循环20多次。如果我切换,它可能会使它循环一个额外的时间,因为峰值内存较低,但它不应该解决整个问题。事实上。您的“
文件”
”也可能存储了自己的缓冲区。目前无法检查,但请尝试在GAE文件对象上查找
flush
方法。