Какой правильный способ записи в Blobstore Google App Engine в виде файла в Python 2.5 - PullRequest
2 голосов
/ 09 февраля 2012

Я в настоящее время превышаю предел мягкой памяти, когда пытаюсь делать простые записи в интернет-магазин Google App Engine.Как правильно написать этот код, чтобы он не пропускал память?

from __future__ import with_statement
from google.appengine.api import files
from google.appengine.api import blobstore
def files_test(limit):
file_name = files.blobstore.create(mime_type='application/octet-stream') 
   try:
     with files.open(file_name, 'a') as f:
       for x in range(limit):
         f.write("Testing \n")

   finally:
     files.finalize(file_name)
     return files.blobstore.get_blob_key(file_name)

files_test (4000) выдает ошибку:

Превышен предел мягкой частной памяти с 157,578 МБ после обслуживания 27 запросов всего

Ответы [ 4 ]

3 голосов
/ 10 февраля 2012

К сожалению, сборщик мусора в python не идеален. Каждая сделанная вами запись создает множество небольших объектов (посредством создания буфера протокола), которые почему-то не собираются python на лету. Я обнаружил, что в библиотеке mapreduce мне нужно сделать

import gc
gc.collect()

время от времени, чтобы сборщик мусора был доволен.

0 голосов
/ 05 июня 2012

Может быть, я ошибаюсь, но я вполне уверен, что количество вызовов write () может быть проблемой здесь.Я думаю, что это проблема, потому что у меня была похожая проблема, когда я пытался сохранить файл, который был загружен пользователем.

Для меня это было причиной проблемы:

with files.open(file_name, 'a') as f:
    for chunk in read_in_chunks(data):
        f.write(chunk)    

Дляпроблема исчезла, когда я изменил размер куска на 1 МБ вместо 1 КБ.

0 голосов
/ 12 февраля 2012

Вы должны записать все данные одновременно, чтобы избежать проблемы и ускорить ее - оптимизировать - это должно остановить проблему, но не устранить ошибку -> http://docs.python.org/library/stringio.html. Учтите, что file.write может быть не простой записью, а запросом к RPC API, который медленно настраивается - см. Код SDK - избегайте нескольких вызовов / буфера.

При таком небольшом количестве данных 4000 * 9 это не должно происходить - похоже на ошибку в Google API - просто сообщите об этом http://code.google.com/p/googleappengine/issues/list?can=2&q=&sort=-id&colspec=ID%20Type%20Component%20Status%20Stars%20Summary%20Language%20Priority%20Owner%20Log

Учтите, что 'create' помечен как экспериментальный http://code.google.com/intl/pl/appengine/docs/python/blobstore/overview.html#Writing_Files_to_the_Blobstore

Исправлено также исправление ошибок - не завершать неверный файл и не возвращать результат, если исключение!

import StringIO

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

def files_test(limit):
    output = StringIO.StringIO()

    # workaround!
    for x in range(limit):
        output.write("Testing \n")

    file_name = files.blobstore.create(mime_type='application/octet-stream') 
    try:
        with files.open(file_name, 'a') as f:
            # workaround!
            f.write(output.getvalue())

    finally:
        output.close()

    files.finalize(file_name)           
    return files.blobstore.get_blob_key(file_name)
0 голосов
/ 10 февраля 2012

Поскольку это Python 2.5, xrange должно быть лучше, чем range, не так ли?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...