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

时间:2009-06-30 08:52:28

标签: google-app-engine google-cloud-datastore

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

29 个答案:

答案 0 :(得分:69)

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

如果您正在谈论 development datastore ,则只需删除以下文件:“./ WEB-INF / appengine-generated / local_db。 BIN“即可。下次运行开发服务器时,将再次为您生成该文件,并且您将拥有一个明确的数据库。

确保事后清理项目。

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

答案 1 :(得分:58)

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

这并不困难,最新的1.2.5 SDK提供了现成的remote_shell_api.py。所以去下载新的SDK。然后按照以下步骤操作:

  • 在命令行中连接远程服务器:remote_shell_api.py yourapp /remote_api shell将询问您的登录信息,如果获得授权,将为您创建一个Python shell。您需要在app.yaml

  • 中为/ remote_api设置网址处理程序
  • 获取您要删除的实体,代码如下所示:

    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,您应根据the documentationremote_api_shell.py -s your_app_id.appspot.com联系。

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

答案 2 :(得分:27)

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

如果您选择的语言为Python,则只需在 mapreduce.yaml 文件中注册映射器并定义如下函数:

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

Java上,你应该看看this article建议这样的函数:

@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开始,为此目的有一个Datastore admin feature

答案 3 :(得分:26)

运行服务器时可以clear the development server datastore

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

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

答案 4 :(得分:15)

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

答案 5 :(得分:11)

您可以:转到数据存储区管理员,然后选择要删除的实体类型,然后单击“删除”。 Mapreduce将负责删除!

答案 6 :(得分:9)

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

enter image description here

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

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

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

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

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

  6. 或者你可以使用Mapreduce来获得更强大和更有魅力的东西。

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

    希望它有所帮助!

答案 7 :(得分:6)

执行此操作的零设置方法是向管理服务发送执行任意代码HTTP请求,您的运行应用已经自动执行:

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

答案 8 :(得分:3)

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

答案 9 :(得分:3)

这就是你要找的......

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

运行仅限密钥的查询比完全提取要快得多,而且您的配额会受到较小的影响,因为仅限密钥的查询被视为小型操作。

这是来自尼克约翰逊的link to an answer进一步描述。

以下是截断表格的端到端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 decorator

最后,该行动被称为:

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

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

答案 10 :(得分:3)

为您的应用程序打开“Datastore Admin”并启用Admin。然后将列出所有实体的复选框。您只需选择不需要的entites并删除它们即可。

答案 11 :(得分:3)

您可以通过逐个删除所有种类来删除所有数据存储。 与谷歌appengine仪表板。请按照以下步骤操作。

  1. 登录https://console.cloud.google.com/datastore/settings
  2. 单击打开数据存储管理。 (如果未启用,则启用它。)
  3. 选择所有实体并按删除。(此步骤运行地图减少作业以删除所有选定的种类。)
  4. 有关详细信息,请参阅此图片http://storage.googleapis.com/bnifsc/Screenshot%20from%202015-01-31%2023%3A58%3A41.png

答案 12 :(得分:3)

对于Python,1.3.8包含一个内置的实验性管理员。他们say:“在app.yaml文件中启用以下内置功能:”

builtins:
- datastore_admin: on
  

“数据存储删除目前仅适用于Python运行时。但是,Java应用程序仍然可以通过创建在app.yaml中启用数据存储管理的非默认Python应用程序版本来利用此功能。对Java的本机支持将包含在即将发布的版本中。“

答案 13 :(得分:3)

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

答案 14 :(得分:3)

来源

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

创建交互式控制台

首先,您需要定义一个交互式的appenginge控制台。因此,创建一个名为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)

Mapper应该只是一个抽象类,它允许您遍历给定类型的每个实体,无论是提取数据,还是修改它们并将更新的实体存储回数据存储区。

用它跑!

现在,启动你的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()

就是这样!

答案 15 :(得分:2)

添加关于最近发展的答案。

Google最近添加了数据存储区管理功能。您可以使用此控制台将实体备份,删除或复制到另一个应用程序。

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

答案 16 :(得分:2)

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

答案 17 :(得分:2)

对于开发服务器,您可以通过Google应用引擎启动器运行服务器,而不是通过以下方式运行服务器:

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

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

这对我有好处。

答案 18 :(得分:1)

我经常不想删除所有数据存储,因此我将/war/WEB-INF/local_db.bin的干净副本拉出源控件。它可能只是我,但似乎即使启动模式停止我必须在拉动之前物理删除文件。这是在Windows上使用Eclipse的subversion插件。

答案 19 :(得分: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

答案 20 :(得分:0)

如果你正在使用ndb,这个方法对我有用,可以清除数据存储区:

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

答案 21 :(得分:0)

对于应用引擎上的任何数据存储,而不是本地数据存储,您可以使用new Datastore API。这是a primer for how to get started

我编写了一个删除所有非内置实体的脚本。 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()

答案 22 :(得分: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秒。

答案 23 :(得分:0)

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

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

答案 24 :(得分:0)

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

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

  • 可以通过查询大块的记录删除没有失败的记录(至少在本地工作),并且可以在时间结束时继续下次尝试:


    qdelete.getFetchPlan().setFetchSize(100);

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

答案 25 :(得分:0)

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

  1. 停止开发服务器。
  2. 删除目标目录。
  3. 重建项目。
  4. 这将擦除数据存储区中的所有数据。

答案 26 :(得分: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中运行良好

答案 27 :(得分:0)

您有2种简单的方法,

#1:为节省成本,请删除整个项目

#2:使用ts-datastore-orm:

https://www.npmjs.com/package/ts-datastore-orm 等待Entity.truncate(); 截断每秒可以删除约1K行

答案 28 :(得分:0)

这是我从python3的香草Google Cloud Shell(无GAE)中天真地做的事情:

from google.cloud import datastore
client = datastore.Client()
query.keys_only()
for counter, entity in enumerate(query.fetch()):
    if entity.kind.startswith('_'):  # skip reserved kinds
        continue
    print(f"{counter}: {entity.key}")
    client.delete(entity.key)

即使键的数量相对较少,也要花费很长时间,但是它可以正常工作。

有关Python客户端库的更多信息:https://googleapis.dev/python/datastore/latest/client.html