有人知道如何删除Google App Engine中的所有数据存储吗?
/path/to/google_appengine/dev_appserver.py --clear_datastore yes myappname/
其中myappname是您的目录,其中包含该应用程序的app.yaml文件。
有人知道如何删除Google App Engine中的所有数据存储吗?
/path/to/google_appengine/dev_appserver.py --clear_datastore yes myappname/
其中myappname是您的目录,其中包含该应用程序的app.yaml文件。
Answers:
如果您正在谈论实时数据存储,请打开应用的仪表板(在appengine上登录),然后打开数据存储-> dataviewer,选择要删除的表的所有行,然后单击Delete按钮(您必须为您的所有表格执行此操作)。您可以通过remote_api以编程方式进行相同操作(但我从未使用过)。
如果您在谈论开发数据存储区,则只需删除以下文件:“ ./WEB-INF/appengine-generation/local_db.bin”。下次您运行开发服务器时,将再次为您生成文件,您将获得一个清晰的数据库。
确保随后清理项目。
这是开始使用Google Application Engine时会派上用场的小陷阱之一。您会发现自己将对象持久化到数据存储中,然后为持久性实体更改JDO对象模型,最终导致过时的数据使应用程序崩溃。
最好的方法是Nick所建议的远程API方法,他是Google的App 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备份数据存储。
处理数据存储区上批量删除的最快,最有效的方法是使用最新Google I / O上宣布的新的mapper API。
如果您选择的语言是Python,则只需将您的映射器注册到mapreduce.yaml文件中,然后定义如下函数:
from mapreduce import operation as op
def process(entity):
yield op.db.Delete(entity)
@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起,为此目的有一个数据存储区管理员功能
您可以在运行服务器时清除开发服务器数据存储:
/path/to/dev_appserver.py --clear_datastore=yes myapp
您也可以缩写--clear_datastore
使用-c
。
/path/to/google_appengine/dev_appserver.py --clear_datastore yes myappname/
(请注意“是”)
您可以使用几种方法从App Engine的数据存储区中删除条目:
首先,考虑是否真的需要删除条目。这很昂贵,不删除它们可能会更便宜。
您可以使用数据存储管理员手动删除所有条目。
您可以使用远程API并以交互方式删除条目。
您可以使用几行代码以编程方式删除条目。
您可以使用“任务队列和游标”批量删除它们。
或者,您可以使用Mapreduce来获得更强大和更高级的功能。
以下博客文章中介绍了这些方法中的每一种:http : //www.shiftedup.com/2015/03/28/how-to-bulk-delete-entries-in-app-engine-datastore
希望能帮助到你!
我从这里得到的 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类。我刚刚创建了一个名为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()
而已!
我创建了一个加载项面板,可与您已部署的App Engine应用程序一起使用。它在下拉列表中列出了数据存储区中存在的种类,您可以单击按钮来计划“任务”,以删除特定种类的所有实体或仅删除所有实体。您可以在这里下载它:http :
//code.google.com/p/jobfeed/wiki/Nuke
这就是您要寻找的...
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()来处理删除一个或多个结果。
您可以通过一一删除所有种类来删除所有数据存储。使用Google Appengine仪表板。请按照以下步骤。
有关更多信息,请参见此图片http://storage.googleapis.com/bnifsc/Screenshot%20from%202015-01-31%2023%3A58%3A41.png
如果您有大量数据,则使用Web界面可能很耗时。通过App Engine Launcher实用程序,您可以通过“在启动时清除数据存储区”复选框一次性删除所有内容。现在,该实用程序可用于Windows和Mac(Python框架)。
添加有关最新动态的答案。
Google最近添加了数据存储区管理功能。您可以使用此控制台将实体备份,删除或复制到另一个应用程序。
https://developers.google.com/appengine/docs/adminconsole/datastoreadmin#Deleting_Entities_in_Bulk
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秒。
import
?将常量定义为对象实例?
如果您使用的是ndb,则适用于我清除数据存储区的方法:
ndb.delete_multi(ndb.Query(default_options=ndb.QueryOptions(keys_only=True)))
Sorry, unexpected error: The kind "__Stat_Kind__" is reserved.
这似乎是Appengine有一些内部统计信息实体可以通过此方法公开(它们的末端可能存在错误?)
对于应用引擎上而不是本地上的任何数据存储,您可以使用新的数据存储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的想法,重用标记为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;
}
我对于删除实时数据存储中所有数据的现有解决方案感到非常沮丧,以至于我创建了一个小型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);
在Development Server中运作良好
您有2种简单的方法,
#1:为节省成本,请删除整个项目
#2:使用ts-datastore-orm:
https://www.npmjs.com/package/ts-datastore-orm 等待Entity.truncate(); 截断每秒可删除约1K行