首页 文章

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

提问于
浏览
120

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

27 回答

  • 3

    如果您正在讨论 live datastore ,请打开应用程序的仪表板(登录appengine)然后数据存储 - > dataviewer,选择要删除的表的所有行并点击删除按钮(您必须执行此操作)这适用于所有表格) . 您可以通过remote_api以编程方式执行相同操作(但我从未使用过它) .

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

    确保事后清理项目 .

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

  • 1

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

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

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

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

    从模型导入Entry
    query = Entry.all(keys_only = True)
    entries = query.fetch(1000)
    db.delete(项)
    \#这可以批量删除1000个实体一次

    Update 2013-10-28

    根据the documentation

    • remote_shell_api.py 已被 remote_api_shell.py 取代,您应该与 remote_api_shell.py -s your_app_id.appspot.com 连接 .

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

  • 3

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

    如果您选择的语言是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());
    }
    

    EDIT:
    从SDK 1.3.8开始,为此目的有一个Datastore admin feature

  • 15

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

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

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

  • 2

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

  • 27

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

  • 68

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

    enter image description here

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

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

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

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

    • 您可以使用任务队列和游标批量删除它们 .

    • 或者你可以使用Mapreduce来获得更强大和更漂亮的东西 .

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

    希望能帮助到你!

  • 2

    执行此操作的零设置方法是向管理服务发送执行任意代码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())'}))
    
  • 58

    来源

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

    而已!

  • 2

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

  • 3

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

  • 11

    对于Python,1.3.8包含一个内置的实验管理员 . 他们say:"enable the following builtin in your app.yaml file:"

    builtins:
    - datastore_admin: on
    

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

  • 3

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

  • 0

    This is what you're looking for...

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

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

    这是尼克约翰逊的一个link to an answer进一步描述 .

    Below is an end-to-end REST API solution to truncating a table...

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

    Here's the route:

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

    Here's the handler:

    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下找到的Inventory),然后调用action参数中指定的正确方法(Inventory.truncate()) .

    @basic_auth是一个装饰器/包装器,为敏感操作(即POST / DELETE)提供身份验证 . 如果您担心安全问题,还可以使用oAuth decorator .

    最后,该动作被称为:

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

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

  • 0

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

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

  • 3

    如果您有大量数据,使用Web界面可能非常耗时 . App Engine Launcher实用程序允许您使用'Clear datastore on launch'复选框一次性删除所有内容 . 此实用程序现在可用于Windows和Mac(Python框架) .

  • 0

    对于开发服务器,您可以从终端运行它,而不是通过谷歌应用引擎启动器运行服务器,如:

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

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

    这对我有好处 .

  • 0

    增加关于最近发展的答案 .

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

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

  • 26

    我经常不想删除所有数据存储,所以我将/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 app样本自动化超过30秒 .

  • 8
    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)))
    
  • 6

    对于应用引擎上的任何数据存储,而不是本地数据存储,您可以使用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()
    
  • 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;
        }
    
    • 有时在主表中创建附加字段而不是将候选(相关记录)放入单独的表中也很有用 . 是的,字段可以是无索引/序列化的数组,只需很少的计算成本 .
  • 3

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

    • 停止开发服务器 .

    • 删除目标目录 .

    • 重建项目 .

    这将擦除数据存储区中的所有数据 .

  • 3

    我对 deleting all data in the live datastore 的现有解决方案感到非常沮丧,因此我创建了一个小型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中运行良好

相关问题