Google App Engine のすべてのデータストアを削除する方法を知っている人はいますか?
ライブデータストアについて話している場合は、アプリのダッシュボードを開き(appengineにログイン)、次にデータストア-> dataviewer、すべての行を選択します削除するテーブルに対して、削除ボタンを押します(すべてのテーブルに対してこれを行う必要があります)。 remote_apiを使用してプログラムで同じことを実行できます(ただし、私は使用しませんでした)。
開発データストアについて話している場合は、次のファイルを削除する必要があります: "./ WEB-INF/appengine-generated/local_db.bin"。次回開発サーバーを実行すると、ファイルが再度生成され、データベースがクリアされます。
後でプロジェクトをきれいにしてください。
これは、Google Application Engineを使い始めるときに役立つ小さな落とし穴の1つです。オブジェクトをデータストアに永続化すると、永続化可能なエンティティのJDOオブジェクトモデルが変更され、アプリが至る所でクラッシュする古いデータになります。
最良のアプローチは、Nickが提案したリモートAPIメソッドです。彼は App EngineGoogleのエンジニアなので、彼を信頼してください。
それほど難しくありません。最新の1.2.5 SDKは、すぐにremote_Shell_api.pyを提供します。新しいSDKをダウンロードしてください。次に、手順に従います。
コマンドラインでリモートサーバーに接続します。remote_Shell_api.py yourapp /remote_api
シェルはログイン情報を要求し、承認された場合、Python Shellを作成します。あなたのapp.yamlで
削除するエンティティを取得すると、コードは次のようになります。
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)
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以降、この目的のために データストア管理機能 があります
開発サーバーのデータストアをクリアする サーバーを実行すると:
/path/to/dev_appserver.py --clear_datastore=yes myapp
--clear_datastore
を-c
で短縮することもできます。
大量のデータがある場合は、スクリプトを使用して削除する必要があります。ただし、remote_apiを使用して、簡単な方法でクライアント側からデータストアをクリアできます。
データストア管理に移動して、削除するエンティティタイプを選択し、[削除]をクリックします。 Mapreduceは削除を処理します!
App Engineのデータストアからエントリを削除するには、いくつかの方法があります。
最初に、本当にエントリを削除する必要があるかどうかを考えます。これは高価で、削除しないほうが安くなる場合があります。
Datastore Adminを使用して、すべてのエントリを手動で削除できます。
リモートAPIを使用して、エントリをインタラクティブに削除できます。
数行のコードを使用して、プログラムでエントリを削除できます。
タスクキューとカーソルを使用して、一括で削除できます。
または、Mapreduceを使用して、より堅牢で手の込んだものを作成することもできます。
これらの方法のそれぞれについて、次のブログ投稿で説明しています: http://www.shiftedup.com/2015/03/28/how-to-bulk-delete-entries-in-app-engine-datastore
それが役に立てば幸い!
これを行うためのゼロセットアップの方法は、実行中のアプリがすでに自動的に持っている管理サービスに任意のコードを実行する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())'}))
デプロイ済みのApp Engineアプリで使用できるアドインパネルを作成しました。データストアに存在する種類がドロップダウンに一覧表示され、ボタンをクリックして、特定の種類のすべてのエンティティまたは単にすべてを削除する「タスク」をスケジュールできます。こちらからダウンロードできます:
http://code.google.com/p/jobfeed/wiki/Nuke
これは 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())
配置したら、このマッパークラスを作成します。私は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()
それでおしまい!
アプリケーションの「データストア管理」を開き、管理を有効にします。次に、すべてのエンティティがチェックボックス付きでリストされます。不要なエンティティを選択して削除するだけです。
これはあなたが探しているものです...
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の下にあるInventory)ことから開始し、アクションパラメーターで指定された正しいメソッド(Inventory.truncate())を呼び出します。
@basic_authは、デリケートな操作(POST/DELETEなど)の認証を提供するデコレーター/ラッパーです。セキュリティが心配な場合は、 oAuthデコレータ も利用できます。
最後に、アクションが呼び出されます:
def truncate(self):
db.delete(Inventory.all(keys_only=True))
それは魔法のように見えますが、実際には非常に簡単です。最良の部分は、モデルに別のアクションを追加することにより、delete()を再利用して1対多の結果の削除を処理できることです。
Pythonの場合、1.3.8には実験的な管理者が組み込まれています。それらは say : "app.yamlファイルで次のビルトインを有効にします:"
builtins:
- datastore_admin: on
「現在、データストアの削除はPythonランタイムでのみ使用可能です。ただし、Javaアプリケーションは、デフォルト以外のPythonアプリケーションを作成することでこの機能を利用できます。 app.yamlでDatastore Adminを有効にするバージョン。Javaのネイティブサポートは、今後のリリースに含まれます。」
すべての種類を1つずつ削除することで、すべてのデータストアを削除できます。 Google AppEngineダッシュボードを使用します。これらの手順に従ってください。
詳細については、この画像を参照してください http://storage.googleapis.com/bnifsc/Screenshot%20from%202015-01-31%2023%3A58%3A41.png
Webインターフェースを使用して実行できます。アカウントにログインし、左側のリンクでナビゲートします。データストア管理には、データを変更および削除するオプションがあります。それぞれのオプションを使用します。
開発サーバーの場合、Google App Engineランチャーを介してサーバーを実行する代わりに、ターミナルから次のように実行できます。
dev_appserver.py --port = [portnumber] --clear_datastore = yes [アプリケーション名]
例:アプリケーション「リーダー」はポート15080で実行されます。コードを変更してサーバーを再起動した後、「dev_appserver.py --port = 15080 --clear_datastore = yes reader」を実行するだけです。
それは私にとって良いことです。
最近の開発に関する回答を追加します。
Googleは最近、データストア管理機能を追加しました。このコンソールを使用して、エンティティを別のアプリにバックアップ、削除、またはコピーできます。
https://developers.google.com/appengine/docs/adminconsole/datastoreadmin#Deleting_Entities_in_Bulk
大量のデータがある場合、Webインターフェースの使用には時間がかかる可能性があります。 App Engine Launcher ユーティリティを使用すると、[起動時にデータストアをクリア]チェックボックスを使用してすべてを一度に削除できます。このユーティリティは、WindowsとMac(Pythonフレームワーク)の両方で利用できるようになりました。
すべてのデータストアを削除したくないことが多いので、/ war/WEB-INF/local_db.binのクリーンコピーをソース管理から取り出します。私だけかもしれませんが、Dev Modeが停止していても、ファイルをプルする前に物理的に削除する必要があります。これは、Eclipse用のSubversionプラグインを使用するWindows上にあります。
ライブデータストア内のすべてのデータを削除する既存のソリューションに非常に不満を感じていたため、その中のかなりの量のデータを削除できる小さなGAEアプリを作成しました30秒。
インストール方法など: https://github.com/xamde/xydra
svpinoの考え方を続けて、削除としてマークされたレコードを再利用することは賢明です。 (彼のアイデアは削除することではなく、「削除済み」未使用レコードとしてマークすることでした)。作業コピーを処理し、状態の違いのみ(目的のタスクの前後)をデータストアに書き込むためのキャッシュ/ memcacheの少しはそれを改善します。大きなタスクの場合、memcacheが消失した場合にデータの損失を回避するために、中間の差分チャンクをデータストアに書き込むことができます。損失を防ぐために、memcachedの結果の整合性/存在をチェックし、タスク(または必要な部分)を再起動して、欠落した計算を繰り返すことができます。データの差分がデータストアに書き込まれると、必要な計算はキューで破棄されます。
縮小されたマップに似た他のアイデアは、シャードエンティティの種類をいくつかの異なるエンティティの種類に分割することです。そのため、まとめて収集され、単一のエンティティの種類として最終ユーザーに表示されます。エントリは「削除済み」としてのみマークされます。シャードごとの「削除された」エントリの量がある程度の制限を超えると、「生きた」エントリは他のシャードに分配され、このシャードは永久に閉じられ、開発コンソールから手動で削除されます(より少ないコストで推測) 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;
}
ローカルではなく、アプリエンジン上にあるデータストアでは、 新しいデータストア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 = '[email protected]'
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 __== "__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()
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);
開発サーバーでうまく機能します
開発サーバーの迅速なソリューションを必要とするすべての人々(2016年2月の執筆時点):
これにより、データストアからすべてのデータが消去されます。
Ndbを使用している場合、データストアをクリアするために私のために働いた方法:
ndb.delete_multi(ndb.Query(default_options=ndb.QueryOptions(keys_only=True)))
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
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秒かかります。制限です。 30秒を超えて自動化するためにajaxアプリのサンプルを配置することを考えています。