如何删除Google App Engine中的所有数据存储?
有谁知道如何删除Google App Engine中的所有数据存储?
如果您正在讨论实时数据存储 ,请打开您的应用程序的仪表板(在appengine上login),然后select数据存储 – > dataviewer,select要删除的表的所有行并点击删除button(您将不得不为所有的表做这个)。 您可以通过remote_api以编程方式执行相同的操作(但我从来没有使用过)。
如果您正在讨论开发数据存储 ,那么您只需要删除以下文件: “./WEB-INF/appengine-generated/local_db.bin” 。 下次运行开发服务器时,会为你生成一个文件,你将得到一个清晰的数据库。
确保事后清理你的项目。
当您开始使用Google应用程序引擎时,这是一个棘手的问题。 您会发现自己将对象保存到数据存储中,然后更改您的持久性实体的JDO对象模型,最终导致您的应用程序崩溃。
最好的方法是Nickbuild议的远程API方法,他是Google的App Engine工程师,所以相信他。
这并不困难,而最新的1.2.5 SDK提供了远离shell的remote_shell_api.py。 所以去下载新的SDK。 然后按照下面的步骤
-
在你的命令行中连接远程服务器:
remote_shell_api.py yourapp /remote_api
shell会询问你的login信息,如果授权的话,会为你创build一个Python shell。 您需要在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
。 -
数据存储pipe理有一个新的实验function,在应用程序设置中启用后,您可以批量删除以及通过networking用户界面备份数据存储。
在Datastore上处理批量删除的最快速有效的方法是使用最新的Google I / O上发布的新的映射器API 。
如果你select的语言是Python ,你只需要在mapreduce.yaml文件中注册你的映射器,并定义一个这样的函数:
from mapreduce import operation as op def process(entity): yield op.db.Delete(entity)
在Java上,你应该看看这篇文章 ,build议这样的function:
@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以来,有一个数据存储pipe理function用于此目的
运行服务器时,可以清除开发服务器数据存储 :
/path/to/dev_appserver.py --clear_datastore=yes myapp
您也可以用-c
缩写--clear_datastore
。
如果你有大量的数据,你需要使用一个脚本来删除它。 不过,您可以直接使用remote_api从客户端清除数据存储区。
在这里你去:去数据存储pipe理,然后select你想要删除的实体types,然后单击删除。 Mapreduce会照顾删除!
有几种方法可以用来从App Engine的数据存储删除条目:
-
首先,想想你是否真的需要删除条目。 这是昂贵的,不删除它们可能会更便宜。
-
您可以使用数据存储pipe理员手动删除所有条目。
-
您可以使用Remote API并交互删除条目。
-
您可以使用几行代码以编程方式删除条目。
-
您可以使用任务队列和光标批量删除它们。
-
或者你可以使用Mapreduce来获得更强大,更漂亮的东西。
以下博客文章解释了这些方法中的每一种: https : //blog.svpino.com/2015/03/28/how-to-bulk-delete-entries-in-app-engine-datastore
希望它有帮助!
这样做的零设置方式是发送一个执行任意代码的HTTP请求到pipe理服务,您的运行应用程序已经自动,具有:
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())'}))
资源
我从http://code.google.com/appengine/articles/remote_api.html得到了这个。;
创build交互式控制台
首先,您需要定义一个交互式appenginge控制台。 因此,创build一个名为appengine_console.py的文件并input:
#!/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())
创buildMapper基类
一旦到位,创build这个Mapper类。 我刚刚创build了一个名为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应该只是一个抽象类,允许您遍历给定types的每个实体,即提取它们的数据,或修改它们,并将更新后的实体存储回数据存储区。
运行它!
现在,开始你的appengine交互式控制台:
$python appengine_console.py <app_id_here>
这应该启动交互式控制台。 在它中创build一个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()
而已!
你可以使用networking界面来做到这一点。 login到您的帐户,浏览左侧的链接。 在Data Storepipe理中,您可以select修改和删除数据。 使用相应的选项。
我已经创build了一个可以与您部署的App Engine应用程序一起使用的附加面板。 它在下拉列表中列出数据存储区中存在的types,您可以单击button来安排“任务”,以删除特定种类的所有实体或简单的所有事物。 你可以在这里下载:
http://code.google.com/p/jobfeed/wiki/Nuke
对于Python,1.3.8包含一个内置的实验性pipe理员。 他们说 :“在您的app.yaml文件中启用以下内置:”
builtins: - datastore_admin: on
“数据存储删除目前只能在Python运行时使用,不过,Java应用程序仍然可以利用这个function,创build一个非默认的Python应用程序版本来启用app.yaml中的Datastore Admin。在即将发布的版本中。“
打开您的应用程序的“数据存储pipe理员”并启用pipe理员。 然后你所有的实体将被列出checkbox。 您可以简单地select不需要的实体并删除它们。
这就是你要找的…
db.delete(Entry.all(keys_only=True))
运行一个只有键的查询比完整的提取要快得多,而且你的配额将会受到较小的打击,因为只有键的查询被认为是小操作。
尼克·约翰逊(Nick Johnson) 的回答可以链接到这里。
以下是截断表的端到端REST API解决scheme…
我设置了一个REST API来处理数据库事务,其中路由被直接映射到适当的模型/动作。 这可以通过input正确的URL(example.com/inventory/truncate)并login来调用。
路线如下:
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)()
它通过dynamic加载模型(即在api.models下findInventory)开始,然后根据action参数中的指定调用正确的方法(Inventory.truncate())。
@basic_auth是一个装饰/包装,为敏感操作提供authentication(即POST / DELETE)。 如果您担心安全问题,还可以使用oAuth装饰器 。
最后,这个动作被称为:
def truncate(self): db.delete(Inventory.all(keys_only=True))
它看起来像魔术,但实际上非常简单。 最好的部分是,delete()可以重新用于处理删除一个或多个结果,方法是向模型添加另一个操作。
如果您有大量数据,使用Web界面可能会耗费大量时间。 通过App Engine启动器实用程序,您可以通过“启动时清除数据存储”checkbox一次性删除所有内容。 此实用程序现在可用于Windows和Mac(Python框架)。
对于开发服务器,而不是通过谷歌应用程序引擎启动器运行服务器,你可以从terminal运行它,如:
dev_appserver.py –port = [portnumber] –clear_datastore = yes [nameofapplication]
例如:我的应用程序“reader”在端口15080上运行。修改代码并重新启动服务器之后,我只运行“dev_appserver.py –port = 15080 –clear_datastore = yes reader”。
这对我有好处
添加有关最新发展的答案。
Google最近添加了数据存储pipe理function。 您可以使用此控制台备份,删除或复制您的实体到另一个应用程序。
https://developers.google.com/appengine/docs/adminconsole/datastoreadmin#Deleting_Entities_in_Bulk
我经常不想删除所有的数据存储,所以我把一个干净的/war/WEB-INF/local_db.bin拷贝出来。 它可能只是我,但似乎即使在开发模式停止,我必须物理删除文件,然后再拉。 这是在Windows上使用Eclipse的颠覆插件。
您可以通过删除所有种类逐个删除所有数据存储。 与谷歌appengine仪表板。 请按照这些步骤。
1-login到https://appengine.google.com/
2-点击数据部分中的数据存储pipe理(如果未启用,则启用数据存储pipe理)。
3-select所有实体,然后按删除(此步骤运行地图缩减作业以删除所有选定的种类)。
欲了解更多信息,请参阅此图像http://storage.googleapis.com/bnifsc/Screenshot%20from%202015-01-31%2023%3A58%3A41.png
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秒。
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
如果您使用的是ndb,那么我的清除数据存储的方法就是:
ndb.delete_multi(ndb.Query(default_options=ndb.QueryOptions(keys_only=True)))
对于应用程序引擎上的任何数据存储,而不是本地数据存储 ,可以使用新的数据存储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()
-
继续svpino的想法是重用标记为删除logging的智慧。 (他的想法是不删除,但标记为“删除”未使用的logging)。 一点点的caching/内存caching处理工作副本,只写入状态差异(在所需的任务之前和之后)到数据存储将使它更好。 对于大任务,可以将最终差异块写入数据存储区,以避免在memcache消失时数据丢失。 为了使其不受损失,可以检查memcached结果的完整性和存在性,并重新启动任务(或需要的部分)以重复丢失的计算。 当数据差异被写入数据存储器时,所需的计算在队列中被丢弃。
-
其他类似于地图的思想是把实体类分割成几种不同的实体types,所以它们将作为单一的实体类集合到最终用户中。条目只被标记为“已删除”。当每个碎片的“已删除”条目数量超过某个限制时,“活动”条目将在其他碎片之间分配,并且该碎片永远closures,然后从开发控制台手动删除(以较低的成本猜测)upd:似乎在控制台,只能按正常价格删除logging。 -
可以通过块查询来删除没有gae失败的大型logging(至less在本地工作),并有可能在时间结束时继续下一次尝试:
qdelete.getFetchPlan().setFetchSize(100); while (true) { long result = qdelete.deletePersistentAll(candidates); LOG.log(Level.INFO, String.format("deleted: %d", result)); if (result <= 0) break; }
- 有时在主表中添加额外的字段而不是将候选(相关logging)放入单独的表中是有用的。 是的,字段可以是非索引/序列化数组,计算成本很低。
对于所有需要开发者服务器快速解决scheme的人员(截至2016年2月):
- 停止开发服务器。
- 删除目标目录。
- 重build项目。
这将清除数据存储区中的所有数据。
我很遗憾现有解决scheme删除实时数据存储中的所有数据 ,我创build了一个小的GAE应用程序,可以在30秒内删除相当数量的数据。
如何安装等: https : //github.com/xamde/xydra
对于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);
在开发服务器中运行良好