如何删除Google App Engine中的所有数据存储?


122

有人知道如何删除Google App Engine中的所有数据存储吗?


2
db.delete(db.Query(keys_only = True))。此处有更多详细信息stackoverflow.com/a/10856555/290340
Evan Plaice 2012年

4
如下面的@systempuntoout所指出的,GAE现在具有一个数据存储管理员,可让您批量删除实体,而无需任何编码。该功能需要在此处浮出水面,而不是在第三条注释中隐藏。
ralfoide 2012年

Datastore Admin不起作用(该页面将iframe加载到不存在的主机上),因此我们仍然需要使用db.delete方法。

要删除开发服务器上的所有数据,请在cmd提示符下发出以下命令:/path/to/google_appengine/dev_appserver.py --clear_datastore yes myappname/ 其中myappname是您的目录,其中包含该应用程序的app.yaml文件。
gsinha 2014年

Answers:


69

如果您正在谈论实时数据存储,请打开应用的仪表板(在appengine上登录),然后打开数据存储-> dataviewer,选择要删除的表的所有行,然后单击Delete按钮(您必须为您的所有表格执行此操作)。您可以通过remote_api以编程方式进行相同操作(但我从未使用过)。

如果您在谈论开发数据存储区,则只需删除以下文件:“ ./WEB-INF/appengine-generation/local_db.bin”。下次您运行开发服务器时,将再次为您生成文件,您将获得一个清晰的数据库。

确保随后清理项目。

这是开始使用Google Application Engine时会派上用场的小陷阱之一。您会发现自己将对象持久化到数据存储中,然后为持久性实体更改JDO对象模型,最终导致过时的数据使应用程序崩溃。


16
dev_appserver.py有一个-c参数,可从开发数据存储中删除。
svrist

1
@svrist但这仅适用于Python应用程序引擎。有人知道在Java中执行此操作的快捷方式吗?(在此期间,JohnIdol的建议效果很好。)
mgiuca

2
感谢@John:MAC OSX中的确切路径在哪里?
乔治·阮

3
Windows中的路径在哪里?
Shane Best

2
@ShaneBest Windows中的路径是一样的东西./target/yourappid-1.0-SNAPSHOT/WEB-INF/appengine-generated/local_db.bin
睡眠

58

最好的方法是Nick所建议的远程API方法,他是GoogleApp Engine工程师,所以请相信他。

这样做并不困难,最新的1.2.5 SDK提供了现成的remote_shell_api.py。因此,请下载新的SDK。然后按照下列步骤操作:

  • 在命令行中连接远程服务器:remote_shell_api.py yourapp /remote_api 外壳程序将询问您的登录信息,如果获得授权,将为您制作Python外壳程序。您需要在app.yaml中为/ remote_api安装URL处理程序

  • 获取您要删除的实体,代码如下所示:

    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

更新2013-10-28

  • remote_shell_api.py根据文档中的内容已被替换remote_api_shell.py,您应该与之联系。remote_api_shell.py -s your_app_id.appspot.com

  • 有一个新的实验性功能Datastore Admin,在应用程序设置中启用它后,您可以批量删除以及通过Web ui备份数据存储。


17
实际上,您不需要提取。只需db.delete(Entry.all())即可。
下载

4
您需要在500个实体集中执行此操作,否则将得到:BadRequestError:一次调用不能删除500个以上的实体
marcc 2010年

1
仅供参考,要使用远程api,您需要首先在YAML文件中使用buildins:-remote_api:在应用程序中启用它。有关更多信息,请访问developers.google.com/appengine/articles/remote_api
Zaffiro,2012年

2
至少在调用Entry.all()时添加“ keys_only = True”。如果您不需要检查数据,则无需获取整个条目。否则,您只是在浪费计算周期。
Evan Plaice 2012年

1
+1 ...但是:自2013年起,remote_shell_api.py不存在。当前的脚本名称是remote_api_shell.py。另外,如果您使用ndb(这是当今大多数人的工作方式),则建议使用ndb.delete_multi(model.Entry.query()。fetch(keys_only = True))的方式
Uri,

27

处理数据存储区上批量删除的最快,最有效的方法是使用最新Google I / O上宣布的新的mapper API

如果您选择的语言是Python,则只需将您的映射器注册到mapreduce.yaml文件中,然后定义如下函数:

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

Java上,您应该看一下这篇建议使用以下功能的文章

@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());
}

编辑:
自SDK 1.3.8起,为此目的有一个数据存储区管理员功能


27

您可以在运行服务器时清除开发服务器数据存储

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

您也可以缩写--clear_datastore使用-c


5
不确定是否是最近的事情,但是现在的实际语法是/path/to/google_appengine/dev_appserver.py --clear_datastore yes myappname/(请注意“是”)
Melllvar

这是在开发过程中重复删除数据存储的最有用的方法。随着选项很快变得过时,值得强调的是,该标志在2018年7月仍然存在,并且适用于通过gcloud CLI安装的dev_appserver
Michael

在Google Cloud SDK 270.0.0版本中,“-clear_datastore = yes”仍然可以使用等号
弗兰克桑德

15

如果您有大量数据,则需要使用脚本将其删除。但是,您可以使用remote_api从客户端清除数据存储区。


11

解决方法:转到“数据存储管理”,然后选择要删除的实体类型,然后单击“删除”。Mapreduce将负责删除!


9

您可以使用几种方法从App Engine的数据存储区中删除条目:

在此处输入图片说明

  1. 首先,考虑是否真的需要删除条目。这很昂贵,不删除它们可能会更便宜。

  2. 您可以使用数据存储管理员手动删除所有条目。

  3. 您可以使用远程API并以交互方式删除条目。

  4. 您可以使用几行代码以编程方式删除条目。

  5. 您可以使用“任务队列和游标”批量删除它们。

  6. 或者,您可以使用Mapreduce来获得更强大和更高级的功能。

以下博客文章中介绍了这些方法中的每一种:http : //www.shiftedup.com/2015/03/28/how-to-bulk-delete-entries-in-app-engine-datastore

希望能帮助到你!


6

零设置方法是将执行任意代码的HTTP请求发送到您正在运行的应用程序已自动具有的admin服务:

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())'}))

这仅适用于开发服务器。有相当于产量的产品吗?
盖迪2011年

3

资源

我从这里得到的 http://code.google.com/appengine/articles/remote_api.html

创建交互式控制台

首先,您需要定义一个交互式附件控制台。因此,创建一个名为appengine_console.py的文件并输入以下内容:

#!/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())



创建Mapper基类

到位后,创建此Mapper类。我刚刚创建了一个名为utils.py的新文件,并将其抛出:

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)

映射器应该只是一个抽象类,它允许您遍历给定类型的每个实体,无论是提取其数据还是对其进行修改并将更新后的实体存储回数据存储中。

运行它!

现在,启动您的appengine交互式控制台:

$python appengine_console.py <app_id_here>

那应该启动交互式控制台。在其中创建Model的子类:

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

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

最后,从您的交互式控制台运行它:mapper = MyModelDeleter()mapper.run()

而已!


3

您可以使用网络界面进行操作。登录到您的帐户,使用左侧的链接进行导航。在数据存储管理中,您可以选择修改和删除数据。使用相应的选项。


3

我创建了一个加载项面板,可与您已部署的App Engine应用程序一起使用。它在下拉列表中列出了数据存储区中存在的种类,您可以单击按钮来计划“任务”,以删除特定种类的所有实体或仅删除所有实体。您可以在这里下载它:http :
//code.google.com/p/jobfeed/wiki/Nuke


3

对于Python,1.3.8为此提供了一个内置的实验管理员。他们:“在app.yaml文件中启用以下内置功能:”

builtins:
- datastore_admin: on

“数据存储删除目前仅在Python运行时中可用。但是,Java应用程序仍可以通过创建非默认的Python应用程序版本(在app.yaml中启用Datastore Admin)来利用此功能。将包括对Java的本地支持在即将发布的版本中。”


在app.yaml中添加配置会引发错误。相反,我们可以从“管理”部分的“应用程序设置”页面启用它。有一个按钮可以启用它
Sundeep

3

打开您的应用程序的“数据存储区管理员”并启用管理员。然后,所有实体都将带有复选框列出。您可以简单地选择不需要的实体并将其删除。


3

这就是您要寻找的...

db.delete(Entry.all(keys_only=True))

运行仅键查询比完全获取要快得多,并且由于仅键查询被视为小型操作,因此配额的命中率会较小。

这是尼克·约翰逊(Nick Johnson)给出的答案链接,对其进行了进一步描述。

以下是用于截断表的端到端REST API解决方案...

我设置了一个REST API来处理数据库事务,其中路由直接映射到正确的模型/操作。可以通过输入正确的URL(example.com/inventory/truncate)并登录来调用。

这是路线:

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

这是处理程序:

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)()

首先从动态加载模型(即在api.models下找到库存)开始,然后调用action参数中指定的正确方法(Inventory.truncate())。

@basic_auth是一个修饰器/包装器,它为敏感操作(即POST / DELETE)提供身份验证。如果您担心安全性,也可以使用oAuth装饰器

最后,该动作称为:

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

它看起来像魔术,但实际上非常简单。最好的部分是,可以通过在模型中添加其他操作来重新使用delete()来处理删除一个或多个结果。


3

您可以通过一一删除所有种类来删除所有数据存储。使用Google Appengine仪表板。请按照以下步骤。

  1. 登录到https://console.cloud.google.com/datastore/settings
  2. 单击打开数据存储管理。(如果未启用,请启用。)
  3. 选择所有实体,然后按Delete键。(此步骤运行地图归约作业,以删除所有选定的种类。)

有关更多信息,请参见此图片http://storage.googleapis.com/bnifsc/Screenshot%20from%202015-01-31%2023%3A58%3A41.png


2

如果您有大量数据,则使用Web界面可能很耗时。通过App Engine Launcher实用程序,您可以通过“在启动时清除数据存储区”复选框一次性删除所有内容。现在,该实用程序可用于Windows和Mac(Python框架)。


2

对于开发服务器,您可以从终端运行它,而不必通过google app引擎启动器运行该服务器:

dev_appserver.py --port = [端口号] --clear_datastore =是[应用程序名称]

例如:我的应用程序“阅读器”在端口15080上运行。修改代码并重新启动服务器后,我只需运行“ dev_appserver.py --port = 15080 --clear_datastore = yes阅读器”。

对我有好处



1

我通常不想删除所有数据存储,因此我将/war/WEB-INF/local_db.bin的干净副本拉出了源代码管理。可能只是我一个人,但即使在开发模式停止的情况下,我也必须在拉动文件之前物理删除该文件。这是在Windows上使用Eclipse的Subversion插件。


0

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);
        }
    }
}

是的,这需要时间和30秒。是一个极限。我正在考虑将ajax应用程序示例自动化超过30秒。


这甚至不是有效的php。import?将常量定义为对象实例?
乔什J

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

0

如果您使用的是ndb,则适用于我清除数据存储区的方法:

ndb.delete_multi(ndb.Query(default_options=ndb.QueryOptions(keys_only=True)))

1
我认为这行不通。Appengine抱怨Sorry, unexpected error: The kind "__Stat_Kind__" is reserved.这似乎是Appengine有一些内部统计信息实体可以通过此方法公开(它们的末端可能存在错误?)
消失了

0

对于应用引擎上而不是本地上的任何数据存储,您可以使用新的数据存储API。这是入门的入门

我编写了一个脚本,该脚本删除了所有非内置实体。API的变化非常快,因此仅供参考,我在提交990ab5c7f2063e8147bcc56ee222836fd3d6e15b处将克隆了

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 = 'XXXXXXXX@developer.gserviceaccount.com'
  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()

0
  • 继续svpino的想法,重用标记为delete的记录是明智的。(他的想法不是删除,而是标记为“已删除”的未使用记录)。少量的缓存/内存缓存可以处理工作副本,并且仅将状态差异(在所需任务之前和之后)写入数据存储区会更好。对于大型任务,可以将中间差异块写入数据存储区,以避免如果内存缓存消失,则数据丢失。为了使其防丢失,可以检查memcached结果的完整性/存在性,然后重新启动任务(或必需的部分)以重复丢失的计算。当数据差异写入数据存储时,所需的计算将在队列中丢弃。

  • 类似于map简化的另一个想法是将实体类型分片为几种不同的实体类型,因此它将被收集在一起,并作为单个实体类型对最终用户可见。条目仅标记为“已删除”。当每个分片的“已删除”条目数量超过某个限制时,“活动”条目会在其他分片之间分配,并且该分片将永久关闭,然后从开发人员控制台手动删除(猜测价格较低) upd:控制台上似乎没有删除表,仅删除正常价格的记录。

  • 通过查询可以删除大的记录集,而不会导致gae失败(至少在本地工作),并且有可能在时间结束时继续进行下一次尝试:


    qdelete.getFetchPlan().setFetchSize(100);

    while (true)
    {
        long result = qdelete.deletePersistentAll(candidates);
        LOG.log(Level.INFO, String.format("deleted: %d", result));
        if (result <= 0)
            break;
    }
  • 有时在主表中添加其他字段也很有用,而不是将候选项(相关记录)放入单独的表中。是的,字段可能是未索引/序列化的数组,而计算成本却很少。

0

对于需要为开发服务器提供快速解决方案的所有人(截至撰写本文时为2016年2月):

  1. 停止开发服务器。
  2. 删除目标目录。
  3. 重建项目。

这将清除数据存储中的所有数据。


0

我对于删除实时数据存储所有数据的现有解决方案感到非常沮丧,以至于我创建了一个小型GAE应用,可以在30秒内删除相当数量的数据。

如何安装等:https : //github.com/xamde/xydra


0

对于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);

在Development Server中运作良好


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.