Как проще всего удалить все данные моего хранилища больших двоичных объектов?

Каков наилучший способ удалить все BLOB-объекты из blobstore? Я использую Python.

У меня довольно много BLOB-объектов, и я хотел бы удалить их все. В настоящее время я делаю следующее:

class deleteBlobs(webapp.RequestHandler): 
    def get(self): 
        all = blobstore.BlobInfo.all(); 
        more = (all.count()>0) 
        blobstore.delete(all); 
        if more: 
            taskqueue.add(url='/deleteBlobs',method='GET'); 

Который, кажется, использует тонны ЦП и (насколько я могу судить) не делает ничего полезного.


person defuz    schedule 08.09.2011    source источник


Ответы (2)


Вы передаете объект запроса методу удаления, который будет перебирать его, извлекая его партиями, а затем отправляет одно огромное удаление. Это неэффективно, поскольку требует множественных выборок и не будет работать, если у вас больше результатов, чем вы можете получить за доступное время или доступную память. Задача либо завершится один раз и вообще не потребует цепочки, либо, что более вероятно, будет неоднократно терпеть неудачу, поскольку она не может получить каждый большой двоичный объект одновременно.

Кроме того, вызов count выполняет запрос только для определения количества, что является пустой тратой времени, поскольку вы все равно попытаетесь получить результаты.

Вместо этого вы должны получать результаты пакетами, используя fetch, и удалять каждый пакет. Используйте курсоры, чтобы установить следующий пакет и избежать необходимости повторения запроса по всем «захороненным» записям, прежде чем найти первую живую, и в идеале удалить несколько пакетов для каждой задачи, используя таймер, чтобы определить, когда вы должны остановиться и связать следующее задание.

person Nick Johnson    schedule 09.09.2011

Я использую этот подход:

import datetime
import logging
import re
import urllib

from google.appengine.ext import blobstore
from google.appengine.ext import db
from google.appengine.ext import webapp

from google.appengine.ext.webapp import blobstore_handlers
from google.appengine.ext.webapp import util
from google.appengine.ext.webapp import template

from google.appengine.api import taskqueue
from google.appengine.api import users


class IndexHandler(webapp.RequestHandler):
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.out.write('Hello. Blobstore is being purged.\n\n')
        try:
            query = blobstore.BlobInfo.all()

            index = 0

            to_delete = []
            blobs = query.fetch(400)
            if len(blobs) > 0:
                for blob in blobs:
                    blob.delete()
                    index += 1

            hour = datetime.datetime.now().time().hour
            minute = datetime.datetime.now().time().minute
            second = datetime.datetime.now().time().second
            self.response.out.write(str(index) + ' items deleted at ' + str(hour) + ':' + str(minute) + ':' + str(second))
            if index == 400:
                self.redirect("/purge")

        except Exception, e:
            self.response.out.write('Error is: ' + repr(e) + '\n')
            pass

APP = webapp.WSGIApplication(
    [
        ('/purge', IndexHandler),
    ],
    debug=True)

def main():
    util.run_wsgi_app(APP)


if __name__ == '__main__':
    main()

По моему опыту, более 400 больших двоичных объектов одновременно не работают, поэтому я позволяю ему перезагружаться для каждых 400. Я пробовал blobstore.delete(query.fetch(400)), но я думаю, что сейчас есть ошибка. Вообще ничего не произошло, и ничего не было удалено.

person beruic    schedule 05.11.2011
comment
работал на меня. несколько замечаний: 1/ вывод виден только после завершения загрузки страницы, в моем случае это произошло только в конце последнего перенаправления (последний запрос 400). 2/ у меня все еще была пара ошибок http 500, поэтому я просто перезагружала страницу всякий раз, когда это происходило, и она продолжала удалять капли. - person Ben G; 04.06.2012
comment
Вам не нужно проверять if len(blobs) > 0 перед повторением больших двоичных объектов. В Python можно безопасно перебирать пустую коллекцию. - person Attila O.; 08.05.2013
comment
У вас возникнут проблемы только в том случае, если это None, как упомянул @Attila, безопасно перебирать пустые коллекции. В любом случае вы можете быть в безопасности с помощью if blobs:, поскольку python вернет false для 0, пустой коллекции или None. - person topless; 05.02.2014