Google App Engineのすべてのデータストアを削除する方法を知っている人はいますか?
29 に答える
ライブ データストアについて話している場合は、アプリのダッシュボードを開き (appengine にログイン)、データストア --> データ ビューアーを開き、削除するテーブルのすべての行を選択して、削除ボタンを押します (すべてのテーブルに対してこれを行います)。remote_api を使用してプログラムで同じことを行うことができます (ただし、私は使用したことがありません)。
開発データストアについて話している場合は、 「./WEB-INF/appengine-generated/local_db.bin」というファイルを削除するだけです。次回開発サーバーを実行すると、ファイルが再び生成され、クリアなデータベースが作成されます。
その後、必ずプロジェクトをクリーンアップしてください。
これは、Google Application Engine を使い始めるときに役立つちょっとした落とし穴の 1 つです。オブジェクトをデータストアに永続化してから、永続化可能なエンティティの 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 を介してデータストアを一括削除およびバックアップできます。
Datastore で一括削除を処理する最速かつ効率的な方法は、最新のGoogle I/Oで発表された新しいマッパー 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を使用すると、クライアント側からデータストアを簡単にクリアできます。
はじめに: Datastore Admin に移動し、削除するエンティティ タイプを選択して、[削除] をクリックします。Mapreduce が削除を処理します。
App Engine のデータストアからエントリを削除するには、いくつかの方法があります。
まず、エントリを本当に削除する必要があるかどうかを考えてください。これは高価であり、それらを削除しない方が安くなる場合があります。
Datastore Admin を使用して、手動ですべてのエントリを削除できます。
Remote 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())'}))
Pythonの場合、1.3.8にはこのための実験的な管理者が組み込まれています。彼らは言う:「あなたのapp.yamlファイルで次のビルトインを有効にしてください:」
builtins:
- datastore_admin: on
「現在、データストアの削除はPythonランタイムでのみ利用できます。ただし、Javaアプリケーションは、app.yamlでデータストア管理を有効にするデフォルト以外のPythonアプリケーションバージョンを作成することで、この機能を引き続き利用できます。Javaのネイティブサポートが含まれます。今後のリリースで。」
アプリケーションの「データストア管理」を開き、管理を有効にします。次に、すべてのエンティティがチェック ボックス付きで一覧表示されます。不要なエンティティを選択して削除するだけです。
デプロイされた App Engine アプリで使用できるアドイン パネルを作成しました。データストアに存在する種類がドロップダウンに一覧表示され、ボタンをクリックして、特定の種類のすべてのエンティティまたは単にすべてを削除する「タスク」をスケジュールできます。ここからダウンロードできます:
http://code.google.com/p/jobfeed/wiki/Nuke
すべての種類を 1 つずつ削除することで、すべてのデータストアを削除できます。Google appengine ダッシュ ボードを使用します。次の手順に従ってください。
- https://console.cloud.google.com/datastore/settingsにログインします。
- [データストア管理を開く]をクリックします。(有効になっていない場合は有効にします。)
- すべてのエンティティを選択し、削除を押します (このステップでは、選択したすべての種類を削除するためのマップ縮小ジョブを実行します)。
詳細については、この画像を参照してください http://storage.googleapis.com/bnifsc/Screenshot%20from%202015-01-31%2023%3A58%3A41.png
Web インターフェイスを使用して実行できます。アカウントにログインし、左側のリンクを使用して移動します。データ ストア管理では、データを変更および削除するオプションがあります。それぞれのオプションを使用してください。
ソース
私はこれを得た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()
それでおしまい!
これはあなたが探しているものです...
db.delete(Entry.all(keys_only=True))
キーのみのクエリの実行は、フル フェッチよりもはるかに高速であり、キーのみのクエリは小規模な操作と見なされるため、クォータのヒットが小さくなります。
これは、ニック・ジョンソンからの回答へのリンクであり、さらに説明しています。
以下は、テーブルを切り捨てるためのエンドツーエンドの 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() を再利用して、1 つまたは複数の結果の削除を処理できることです。
最近の展開についての回答を追加します。
Google は最近、データストア管理機能を追加しました。このコンソールを使用して、エンティティをバックアップ、削除、または別のアプリにコピーできます。
https://developers.google.com/appengine/docs/adminconsole/datastoreadmin#Deleting_Entities_in_Bulk
大量のデータがある場合、Web インターフェイスを使用すると時間がかかる場合があります。App Engine ランチャーユーティリティでは、 [起動時にデータストアをクリア] チェックボックスを使用して、すべてを一度に削除できます。このユーティリティは、Windows と Mac (Python フレームワーク) の両方で利用できるようになりました。
多くの場合、すべてのデータ ストアを削除したくないので、/war/WEB-INF/local_db.bin のクリーン コピーをソース管理から取り出します。それは私だけかもしれませんが、開発モードが停止していても、プルする前にファイルを物理的に削除する必要があるようです。これは、Eclipse 用の Subversion プラグインを使用する Windows 上にあります。
ndbを使用している場合、データストアをクリアするために私にとってうまくいった方法:
ndb.delete_multi(ndb.Query(default_options=ndb.QueryOptions(keys_only=True)))
開発サーバーの迅速な解決策が必要なすべての人 (2016 年 2 月の執筆時点):
- 開発サーバーを停止します。
- 対象ディレクトリを削除します。
- プロジェクトを再構築します。
これにより、データストアからすべてのデータが消去されます。
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
ライブ データストア内のすべてのデータを削除する既存のソリューションに非常に不満を感じていたため、30 秒以内にかなりの量のデータを削除できる小さな GAE アプリを作成しました。
インストール方法など:https ://github.com/xamde/xydra
ローカルではなく App Engine 上のデータストアでは、新しい Datastore 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()
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 アプリのサンプルを配置することを考えています。