Pergunta sobre google-app-engine, google-cloud-datastore – Como excluir todo o armazenamento de dados no Google App Engine?

122

Alguém sabe como excluir todos os dados armazenadosGoogle App Engine?

db.delete (db.Query (keys_only = True)). Mais detalhes aquistackoverflow.com/a/10856555/290340. Evan Plaice
db.delete(db.Query()) Andrey Gubarev
O Administrador do Datastore não funciona (a página carrega um iframe para um host inexistente), portanto, ainda precisamos usar o método db.delete. user153275
Para excluir todos os dados no servidor de desenvolvimento, emita o seguinte no prompt do cmd:/path/to/google_appengine/dev_appserver.py --clear_datastore yes myappname/  onde myappname é o seu diretório contendo o seu arquivo app.yaml para o aplicativo .. você precisa cd para este caminho de diretório .. crédito: Steven Almeroth e Melllvar para a resposta abaixo gsinha
Como apontado por @systempuntoout abaixo, o GAE agora tem umAdministrador do Datastore que permite excluir entidades em massa sem qualquer codificação, entre outras coisas. Esse recurso precisa ser exibido aqui em vez de ser enterrado no terceiro comentário. ralfoide

Sua resposta

27   a resposta
26

limpar o armazenamento de dados do servidor de desenvolvimento quando você executa o servidor:

/path/to/dev_appserver.py --clear_datastore=yes myapp

Você também pode abreviar--clear_datastore com-c.

Você também pode abreviar "--clear_datastore" com "-c". Steven Almeroth
É a maneira mais útil de excluir repetidamente o armazenamento de dados durante o desenvolvimento. Com as opções se tornando obsoletas rapidamente, vale destacar que essa sinalização ainda está em vigor em julho de 2018 e funciona para o dev_appserver instalado via gcloud CLI Michael
bônus duplo por menos pressionamentos de teclas! nate_weldon
Obrigado @Melllvar, responda atualizado. Steven Almeroth
Não tenho certeza se é algo recente, mas a sintaxe atual é agora/path/to/google_appengine/dev_appserver.py --clear_datastore yes myappname/ (observe o 'sim') Melllvar
3

do App Engine implantados. Ele lista os tipos que estão presentes no armazenamento de dados em uma lista suspensa, e você pode clicar em um botão para agendar "tarefas" que excluem todas as entidades de um tipo específico ou simplesmente tudo. Você pode baixá-lo aqui:
http://code.google.com/p/jobfeed/wiki/Nuke

2

em vez de executar o servidor por meio do iniciador do Google app engine, você pode executá-lo a partir do terminal como:

dev_appserver.py --port = [portnumber] --clear_datastore = yes [nameofapplication]

ex: meu aplicativo "reader" roda na porta 15080. Depois de modificar o código e reiniciar o servidor, eu apenas corro "dev_appserver.py --port = 15080 --clear_datastore = yes reader".

É bom para mim.

3

os um por um. com painel de controle do Google appengine. Por favor, siga estes passos.

Logar emhttps://console.cloud.google.com/datastore/settingsCliqueAbrir o Administrador do Datastore. (Habilite se não estiver habilitado.)Selecione todas as Entidades e pressione Excluir. (Esta etapa executa um trabalho de redução de mapa para excluir todos os tipos selecionados.)

para mais informações veja esta imagemhttp://storage.googleapis.com/bnifsc/Screenshot%20from%202015-01-31%2023%3A58%3A41.png

2

o uso da interface da Web pode ser demorado. oLançador do Google App Engine O utilitário permite que você exclua tudo de uma vez com a caixa de seleção 'Limpar datastore ao iniciar'. Este utilitário está agora disponível para Windows e Mac (framework Python).

0

o método que funcionou para eu limpar o armazenamento de dados:

ndb.delete_multi(ndb.Query(default_options=ndb.QueryOptions(keys_only=True)))
Eu não acho que isso vai funcionar. A Appengine reclama deSorry, unexpected error: The kind "__Stat_Kind__" is reserved. Isto parece que o appengine tem alguma entidade interna de estatísticas que pode ser exposta por este método (possível erro no final?) disappearedng
0

or de desenvolvimento (como o tempo de escrita em fevereiro de 2016):

Pare o servidor dev.Excluir oalvo diretório.Recrie o projeto.

Isso limpará todos os dados do armazenamento de dados.

0

excluindo todos os dados no armazenamento de dados ao vivo que criei um pequeno aplicativo do GAE que pode excluir uma quantidade considerável de dados em seus 30 segundos.

Como instalar etc:https://github.com/xamde/xydra

3
Fonte

http://code.google.com/appengine/articles/remote_api.html.

Crie o console interativo

Primeiro, você precisa definir um console appenginge interativo. Então, crie um arquivo chamado appengine_console.py e insira isto:

#!/usr/bin/python
import code
import getpass
import sys

# These are for my OSX installation. Change it to match your google_appengine paths. sys.path.append("/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine")
sys.path.append("/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/yaml/lib")

from google.appengine.ext.remote_api import remote_api_stub
from google.appengine.ext import db

def auth_func():
  return raw_input('Username:'), getpass.getpass('Password:')

if len(sys.argv) < 2:
  print "Usage: %s app_id [host]" % (sys.argv[0],)
app_id = sys.argv[1]
if len(sys.argv) > 2:
  host = sys.argv[2]
else:
  host = '%s.appspot.com' % app_id

remote_api_stub.ConfigureRemoteDatastore(app_id, '/remote_api', auth_func, host)

code.interact('App Engine interactive console for %s' % (app_id,), None, locals())



Crie a classe base do Mapeador

Assim que estiver em vigor, crie esta classe Mapper. Acabei de criar um novo arquivo chamado utils.py e joguei isto:

class Mapper(object):
  # Subclasses should replace this with a model class (eg, model.Person).
  KIND = None

  # Subclasses can replace this with a list of (property, value) tuples to filter by.
  FILTERS = []

  def map(self, entity):
    """Updates a single entity.

    Implementers should return a tuple containing two iterables (to_update, to_delete).
    """
    return ([], [])

  def get_query(self):
    """Returns a query over the specified kind, with any appropriate filters applied."""
    q = self.KIND.all()
    for prop, value in self.FILTERS:
      q.filter("%s =" % prop, value)
    q.order("__key__")
    return q

  def run(self, batch_size=100):
    """Executes the map procedure over all matching entities."""
    q = self.get_query()
    entities = q.fetch(batch_size)
    while entities:
      to_put = []
      to_delete = []
      for entity in entities:
        map_updates, map_deletes = self.map(entity)
        to_put.extend(map_updates)
        to_delete.extend(map_deletes)
      if to_put:
        db.put(to_put)
      if to_delete:
        db.delete(to_delete)
      q = self.get_query()
      q.filter("__key__ >", entities[-1].key())
      entities = q.fetch(batch_size)

O Mapper deve ser apenas uma classe abstrata que permite iterar sobre cada entidade de um determinado tipo, seja para extrair seus dados ou para modificá-los e armazenar as entidades atualizadas de volta ao armazenamento de dados.

Corra com isso!

Agora, inicie seu console interativo do appengine:

$python appengine_console.py <app_id_here>

Isso deve iniciar o console interativo. Nele crie uma subclasse de Model:

from utils import Mapper
# import your model class here 
class MyModelDeleter(Mapper):
    KIND = <model_name_here>

    def map(self, entity):
        return ([], [entity])

E, finalmente, execute-o (do seu console interativo): mapper = MyModelDeleter () mapper.run ()

É isso aí!

0

Para java

DatastoreService db = DatastoreServiceFactory.getDatastoreService();
List<Key> keys = new ArrayList<Key>();
for(Entity e : db.prepare(new Query().setKeysOnly()).asIterable())
    keys.add(e.getKey());
db.delete(keys);

Funciona bem no servidor de desenvolvimento

58

como sugerido por Nick, ele é umApp Engine engenheiro deGoogleentão confie nele.

Não é tão difícil de fazer, e o último 1.2.5 SDK fornece o remote_shell_api.py fora da prateleira. Então vá para baixar o novo SDK. Então siga os passos:

Conecte o servidor remoto na sua linha de comando:remote_shell_api.py yourapp /remote_api O shell solicitará suas informações de login e, se autorizado, criará um shell Python para você. Você precisa configurar o manipulador de URL para / remote_api no seu app.yaml

buscar as entidades que você gostaria de excluir, o código é algo como:

    from models import Entry
    query = Entry.all(keys_only=True)
    entries =query.fetch(1000)
    db.delete(entries)
    \# This could bulk delete 1000 entities a time

Atualização 2013-10-28:

remote_shell_api.py foi substituído porremote_api_shell.pye você deve se conectar comremote_api_shell.py -s your_app_id.appspot.com, de acordo coma documentação.

Existe um novo recurso experimentalAdministrador do DatastoreDepois de ativá-lo nas configurações do aplicativo, você pode excluir em massa e fazer backup do armazenamento de dados por meio do Web UI.

Pelo menos adicione o 'keys_only = True' quando você chamar Entry.all (). Não há necessidade de buscar toda a entrada se você não precisa verificar os dados. Senão você está apenas perdendo ciclos de computação. Evan Plaice
Você precisa fazer isso em 500 conjuntos de entidades, senão você obterá: BadRequestError: não é possível excluir mais de 500 entidades em uma única chamada marcc
@Juvenn, mais uma pergunta: Existe alguma maneira de automatizar o remote_api_shell, para que eu possa implementar um script (em vez do shell interativo). Uri
Obrigado Evan, eu adicioneikeys_only=True como você sugeriu. Juvenn Woo
15

precisará usar um script para excluí-lo. Você pode usar o remote_api para limpar o armazenamento de dados do lado do cliente de maneira direta.

0

Variação do PHP:

import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.DatastoreServiceFactory;

define('DATASTORE_SERVICE', DatastoreServiceFactory::getDatastoreService());

function get_all($kind) {
    $query = new Query($kind);
    $prepared = DATASTORE_SERVICE->prepare($query);
    return $prepared->asIterable();
}

function delete_all($kind, $amount = 0) {
    if ($entities = get_all($kind)) {
        $r = $t = 0;
        $delete = array();
        foreach ($entities as $entity) {
            if ($r < 500) {
                $delete[] = $entity->getKey();
            } else {
                DATASTORE_SERVICE->delete($delete);
                $delete = array();
                $r = -1;
            }
            $r++; $t++;
            if ($amount && $amount < $t) break;
        }
        if ($delete) {
            DATASTORE_SERVICE->delete($delete);
        }
    }
}

Sim, isso levará tempo e 30 segundos. é um limite. Estou pensando em colocar um exemplo de aplicativo ajax para automatizar além de 30 segundos.

Isso não é nem mesmo válido php.import? Definindo uma constante como uma instância de objeto? Josh J
WTF Nada disso é necessário. Evan Plaice
69

armazenamento de dados ao vivo, abra o painel do seu aplicativo (login no appengine) e depois datastore -> dataviewer, selecione todas as linhas da tabela que deseja excluir e aperte o botão delete (você terá que fazer isso para todas as suas tabelas). Você pode fazer o mesmo programaticamente através do remote_api (mas nunca usei).

armazenamento de dados de desenvolvimento, você só precisa excluir o seguinte arquivo:"./WEB-INF/appengine-generated/local_db.bin". O arquivo será gerado para você novamente na próxima vez que você executar o servidor de desenvolvimento e você terá um banco de dados claro.

Certifique-se de limpar o seu projeto depois.

Essa é uma das pequenas dicas que são úteis quando você começa a usar o Google Application Engine. Você se verá persistindo objetos no armazenamento de dados e, em seguida, alterando o modelo de objeto JDO para suas entidades persistentes, terminando com dados obsoletos que farão com que seu aplicativo trave em todo o lugar.

Onde está o caminho no Windows? Shane Best
@ShaneBest o caminho no windows é algo como ./target/yourappid-1.0-SNAPSHOT/WEB-INF/appengine-generated/local_db.bin morpheus
Obrigado @John: Onde o caminho exato no MAC OSX? George Nguyen
@svrist Mas isso se aplica apenas ao mecanismo de aplicativos Python. Alguém sabe como um atalho para fazer isso em Java? (Nesse meio tempo, a sugestão de JohnIdol funciona bem.) mgiuca
3

o 1.3.8 inclui um admin experimental embutido para isso. Elesdizer: "habilite o seguinte embutido no seu arquivo app.yaml:"

builtins:
- datastore_admin: on

"A exclusão de armazenamento de dados está atualmente disponível apenas com o tempo de execução do Python. No entanto, os aplicativos Java ainda podem aproveitar esse recurso criando uma versão de aplicativo Python não padrão que habilita o Datastore Admin no app.yaml. O suporte nativo a Java será incluído em um próximo lançamento ".

essa é a solução atualmente mais fácil para excluir em massa uma entidade específica systempuntoout
Adicionando a configuração em app.yaml jogou um erro. Em vez disso, podemos ativá-lo na seção "Configuração de aplicativos" na seção "Administração". Há um botão para ativá-lo Sundeep
3

É isso que você está procurando ...

A execução de uma consulta somente de chaves é muito mais rápida do que uma busca completa, e sua cota sofrerá um impacto menor porque as consultas somente de chaves são consideradas pequenas operações.

Aqui está umlink para uma resposta de Nick Johnson descrevendo-o ainda mais.

Abaixo está uma solução de API REST de ponta a ponta para truncar uma tabela ...

Eu configuro uma API REST para manipular transações de banco de dados nas quais as rotas são diretamente mapeadas para o modelo / ação apropriado. Isso pode ser chamado inserindo o URL correto (example.com/inventory/truncate) e efetuando login.

Aqui está o caminho:

Route('/inventory/truncate', DataHandler, defaults={'_model':'Inventory', '_action':'truncate'})

Aqui está o manipulador:

class DataHandler(webapp2.RequestHandler):
  @basic_auth
  def delete(self, **defaults):
    model = defaults.get('_model')
    action = defaults.get('_action')
    module = __import__('api.models', fromlist=[model])
    model_instance = getattr(module, model)()
    result = getattr(model_instance, action)()

Ele começa carregando o modelo dinamicamente (ou seja, Inventory encontrado em api.models) e, em seguida, chama o método correto (Inventory.truncate ()) conforme especificado no parâmetro de ação.

O @basic_auth é um decorador / wrapper que fornece autenticação para operações sensíveis (isto é, POST / DELETE). Há também umoAuth decorador disponível se você estiver preocupado com segurança.

Finalmente, a ação é chamada:

def truncate(self):
  db.delete(Inventory.all(keys_only=True))

Parece mágica, mas na verdade é muito simples. A melhor parte é que delete () pode ser reutilizado para manipular a exclusão de um ou muitos resultados, adicionando outra ação ao modelo.

0

s como delete. (Sua idéia não era remover, mas marcar como registros não utilizados "excluídos"). Um pouco de cache / memcache para lidar com a cópia de trabalho e escrever apenas uma diferença de estados (antes e depois da tarefa desejada) para o armazenamento de dados a tornará melhor. para grandes tarefas, é possível escrever pedaços diferenciais intermediários no armazenamento de dados para evitar a perda de dados se o memcache desaparecer. para torná-lo à prova de perda, é possível verificar a integridade / existência de resultados do memcached e reiniciar a tarefa (ou parte necessária) para repetir cálculos ausentes. quando a diferença de dados é gravada no armazenamento de dados, os cálculos necessários são descartados na fila.

Outra ideia semelhante à redução de mapa é o tipo de entidade de fragmento para vários tipos de entidade diferentes, portanto ele será coletado em conjunto e visível como um único tipo de entidade para o usuário final. as entradas são marcadas apenas como "excluídas". quando o valor de entradas "excluídas" por shard supera algum limite, as entradas "ativas" são distribuídas entre outros shards e esse shard é encerrado para sempre e, em seguida, excluído manualmente do console dev (calcule a um custo menor) upd: parece nenhuma tabela de descarte no console, apenas exclui registro por registro a preço normal.

é possível excluir por consulta por grandes blocos de registros sem que o gae falhe (pelo menos funciona localmente) com a possibilidade de continuar na próxima tentativa quando o tempo acabar:


    qdelete.getFetchPlan().setFetchSize(100);

    while (true)
    {
        long result = qdelete.deletePersistentAll(candidates);
        LOG.log(Level.INFO, String.format("deleted: %d", result));
        if (result <= 0)
            break;
    }
também às vezes é útil fazer campo adicional na tabela principal em vez de colocar candidatos (registros relacionados) em uma tabela separada. e sim, campo pode ser matriz não indexada / serializada com pouco custo de computação.
0

em vez de local, você pode usar onova API do Datastore. Aquiuma cartilha de como começar.

Eu escrevi um script que exclui todas as entidades não incorporadas. A API está mudando muito rapidamente, então, para referência, eu o clonei no commit990ab5c7f2063e8147bcc56ee222836fd3d6e15b

from gcloud import datastore
from gcloud.datastore import SCOPE
from gcloud.datastore.connection import Connection
from gcloud.datastore import query

from oauth2client import client

def get_connection():
  client_email = '[email protected]'
  private_key_string = open('/path/to/yourfile.p12', 'rb').read()

  svc_account_credentials = client.SignedJwtAssertionCredentials(
    service_account_name=client_email,
    private_key=private_key_string,
    scope=SCOPE)

  return Connection(credentials=svc_account_credentials)


def connect_to_dataset(dataset_id):
  connection = get_connection()
  datastore.set_default_connection(connection)
  datastore.set_default_dataset_id(dataset_id)

if __name__ == "__main__":
  connect_to_dataset(DATASET_NAME)
  gae_entity_query = query.Query()
  gae_entity_query.keys_only()
  for entity in gae_entity_query.fetch():
    if entity.kind[0] != '_':
      print entity.kind
      entity.key.delete()
3

navegue com links no lado esquerdo. No gerenciamento do Data Store, você tem opções para modificar e excluir dados. Use as respectivas opções.

2

Recentemente, o Google adicionou o recurso de administração do armazenamento de dados. Você pode fazer backup, excluir ou copiar suas entidades para outro aplicativo usando este console.

https://developers.google.com/appengine/docs/adminconsole/datastoreadmin#Deleting_Entities_in_Bulk

6

TTP execute-arbitrary-code para o serviço administrativo que seu aplicativo em execução já possui, automaticamente:

import urllib
import urllib2

urllib2.urlopen('http://localhost:8080/_ah/admin/interactive/execute',
    data = urllib.urlencode({'code' : 'from google.appengine.ext import db\n' +
                                      'db.delete(db.Query())'}))
Brilhante, exatamente o que eu precisava no meu caso. Mason
Isso só funciona para o servidor de desenvolvimento. Existe um equivalente de produção? Gady
0
for amodel in db.Model.__subclasses__():
                dela=[]
                print amodel
                try:
                    m = amodel()
                    mq = m.all()
                    print mq.count()
                    for mw in mq:
                        dela.append(mw)
                    db.delete(dela)
            #~ print len(dela)

                except:
                    pass
11

Vá para o Administrador do Datastore e, em seguida, selecione o tipo de entidade que você deseja excluir e clique em Excluir. Mapreduce vai cuidar de apagar!

9

p Engine:

Primeiro, pense se você realmente precisa remover as entradas. Isso é caro e pode ser mais barato não removê-los.

Você pode excluir todas as entradas manualmente usando o Administrador do Datastore.

Você pode usar a API remota e remover entradas interativamente.

Você pode remover as entradas programaticamente usando algumas linhas de código.

Você pode removê-los em massa usando as Filas de tarefas e os Cursores.

Ou você pode usar o Mapreduce para obter algo mais robusto e mais sofisticado.

Cada um desses métodos é explicado na postagem do blog a seguir:http://www.shiftedup.com/2015/03/28/how-to-bulk-delete-entries-in-app-engine-datastore

Espero que ajude!

27

Datastore é usando o novoAPI do mapeador anunciou no mais tardarGoogle I / O.

Se a sua língua de escolha éPython, você só precisa registrar seu mapeador em ummapreduce.yaml arquivo e definir uma função como esta:

from mapreduce import operation as op
def process(entity):
 yield op.db.Delete(entity)

EmJava você deveria dar uma olhadaEste artigo que sugere uma função como esta:

@Override
public void map(Key key, Entity value, Context context) {
    log.info("Adding key to deletion pool: " + key);
    DatastoreMutationPool mutationPool = this.getAppEngineContext(context)
            .getMutationPool();
    mutationPool.delete(value.getKey());
}

EDITAR:
Desde o SDK 1.3.8, há umRecurso de administração do armazenamento de dados para este fim

Realmente impressionante. Obrigado. Guido
1

não quero excluir todo o armazenamento de dados, por isso, extraio uma cópia limpa do controle de origem /war/WEB-INF/local_db.bin. Pode ser apenas eu, mas parece que mesmo com o Dev Mode parado eu tenho que remover fisicamente o arquivo antes de puxá-lo. Isso está no Windows usando o plugin de subversão para o Eclipse.

3

Datastore Admin" para seu aplicativo e ative o Admin. Então todas as suas entidades serão listadas com caixas de seleção. Você pode simplesmente selecionar os indesejados e excluí-los.

Perguntas relacionadas