Google App Engineのすべてのデータストアを削除するにはどうすればよいですか?


122

Google App Engineですべてのデータストアを削除する方法を知っている人はいますか?


2
db.delete(db.Query(keys_only = True))。詳細はこちらstackoverflow.com/a/10856555/290340
エヴァンプライス

4
以下の@systempuntooutで指摘されているように、GAEには、特に何もコーディングせずにエンティティを一括で削除できるデータストア管理者がいます。その機能は、3番目のコメントに埋め込むのではなく、ここで明らかにする必要があります。
ラルフォイド

データストア管理が機能しない(ページが存在しないホストにiframeをロードする)ため、db.deleteメソッドを使用する必要があります。

開発サーバーのすべてのデータを削除するに/path/to/google_appengine/dev_appserver.py --clear_datastore yes myappname/ は、コマンドプロンプトで次のコマンドを発行します。myappnameは、アプリのapp.yamlファイルを含むディレクトリです。このディレクトリパスにcdする必要があります。クレジット:下記の回答のSteven AlmerothとMelllvar
gsinha 2014年

回答:


69

ライブデータストアについて話している場合は、アプリのダッシュボードを開き(appengineにログイン)、次にdatastore-> dataviewerを実行して、削除するテーブルのすべての行を選択し、削除ボタンをクリックします(必要です)すべてのテーブルでこれを行います)。プログラムで、remote_apiを使用して同じことを実行できます(ただし、私は使用していません)。

あなたが話をしている場合は、開発データストア:、あなただけの次のファイルを削除する必要があります「./WEB-INF/appengine-generated/local_db.binを」。このファイルは、次に開発サーバーを実行したときに再び生成され、clear dbが作成されます。

後でプロジェクトを必ずクリーンアップしてください。

これは、Google Application Engineを使い始めるときに役立つ、ちょっとした落とし穴の1つです。オブジェクトをデータストアに永続化し、永続化可能なエンティティのJDOオブジェクトモデルを変更すると、アプリがいたるところにクラッシュする古いデータになってしまいます。


16
開発用データストアから削除するdev_appserver.pyには-cパラメータがあります。
svrist

1
@svristしかし、それはPythonアプリエンジンにのみ適用されます。誰かがJavaでそれを行うためのショートカットをどのように知っていますか?(その間、JohnIdolの提案はうまく機能します。)
mgiuca '29

2
ありがとう@John:MAC OSXの正確なパスはどこですか?
George Nguyen、

3
Windowsのパスはどこにありますか?
シェーンベスト

2
@ShaneBest Windowsのパスは./target/yourappid-1.0-SNAPSHOT/WEB-INF/appengine-generated/local_db.bin
morpheus

58

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.pyremote_api_shell.py -s your_app_id.appspot.com、に接続する必要があります

  • 新しい実験的な機能Datastore Adminがあり、アプリ設定で有効にした後、ウェブUIを介してデータストアを一括削除したりバックアップしたりできます。


17
実際には、フェッチは必要ありません。ただdb.delete(Entry.all())がそれを行います。
ダウンロード

4
これを500エンティティセットで行う必要があります。そうしないと、次のような結果になります。BadRequestError:
marcc

1
参考までに、リモートAPIを使用するには、最初にYAMLファイルのbuiltins:-remote_api:を使用して、アプリケーションでそれを有効にする必要があります。詳細については、developers.google.com
appengine / articles / remote_api

2
Entry.all()を呼び出すときに、少なくとも「keys_only = True」を追加します。データをチェックする必要がない場合は、エントリ全体をフェッチする必要はありません。それ以外の場合は、計算サイクルを無駄にしています。
エヴァンプレイス

1
+1 ...しかし:2013現在、remote_shell_api.pyは存在しません。現在のスクリプト名はremote_api_shell.pyです。また、ndbを使用する場合(ほとんどの人が最近行っていることです)、ndb.delete_multi(model.Entry.query()。fetch(keys_only = True))を使用する推奨方法
Uri

27

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以降、この目的のためのデータストア管理機能があります


27

サーバーを実行するときに、開発サーバーのデータストアをクリアできます。

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

あなたも短縮することができます--clear_datastore-c


5
それが最近のものかどうかは/path/to/google_appengine/dev_appserver.py --clear_datastore yes myappname/
わかり

これは、開発中にデータストアを繰り返し削除する最も便利な方法です。オプションが古くなっているため、このフラグを強調する価値は2018年7月にもまだあり、gcloud CLIを介してインストールされたdev_appserverで機能します
Michael

Google Cloud SDKのバージョン270.0.0では、「-clear_datastore = yes」は等号で引き続き機能します
フランクサンド

15

大量のデータがある場合は、スクリプトを使用してデータを削除する必要があります。ただし、remote_apiを使用すると、簡単な方法でクライアント側からデータストアをクリアできます。


11

次に進みます。DatastoreAdminに移動し、削除するエンティティタイプを選択して、[Delete]をクリックします。Mapreduceが削除を処理します!


9

App Engineのデータストアからエントリを削除するには、いくつかの方法があります。

ここに画像の説明を入力してください

  1. まず、本当にエントリを削除する必要があるかどうかを考えます。これは高価であり、それらを削除しない方が安くなる可能性があります。

  2. データストア管理を使用して、すべてのエントリを手動で削除できます。

  3. リモートAPIを使用して、エントリをインタラクティブに削除できます。

  4. 数行のコードを使用して、プログラムでエントリを削除できます。

  5. タスクキューとカーソルを使用して、それらをまとめて削除できます。

  6. または、Mapreduceを使用して、より堅牢で洗練されたものを取得することもできます。

これらの各方法については、次のブログ投稿で説明されています。http//www.shiftedup.com/2015/03/28/how-to-bulk-delete-entries-in-app-engine-datastore

それが役に立てば幸い!


6

これを行うためのゼロセットアップの方法は、実行中のアプリがすでに自動的に持っている管理サービスに、execute-arbitrary-code 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())'}))

これは開発サーバーでのみ機能します。同等の製品はありますか?
Gady

3

ソース

私はこれを手に入れました 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クラスを作成します。私は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()

それでおしまい!


3

Webインターフェイスを使用してそれを行うことができます。アカウントにログインし、左側のリンクで移動します。データストア管理では、データを変更および削除するオプションがあります。それぞれのオプションを使用します。


3

デプロイしたApp Engineアプリで使用できるアドインパネルを作成しました。ドロップダウンにデータストアに存在する種類が一覧表示され、ボタンをクリックして、特定の種類のすべてのエンティティまたは単にすべてを削除する「タスク」をスケジュールできます。こちらからダウンロードできます:http :
//code.google.com/p/jobfeed/wiki/Nuke


3

Pythonの場合、1.3.8には、このための実験的な管理機能が組み込まれています。彼らは言う:「あなたのapp.yamlファイルで次の組み込みを有効にしてください:」

builtins:
- datastore_admin: on

「データストアの削除は現在、Pythonランタイムでのみ使用できます。ただし、Javaアプリケーションは、app.yamlでデータストア管理を有効にするデフォルト以外のPythonアプリケーションバージョンを作成することで、この機能を利用できます。Javaのネイティブサポートが含まれます今後のリリースで。」


app.yamlに設定を追加するとエラーが発生しました。代わりに、「管理」セクションの「アプリケーション設定」ページから有効にできます。それを有効にするボタンがあります
Sundeep

3

アプリケーションの「データストア管理」を開き、管理を有効にします。次に、すべてのエンティティがチェックボックスとともに一覧表示されます。不要なエンティティを選択して削除するだけです。


3

これはあなたが探しているものです...

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)を動的にロードし、次にactionパラメーターで指定されている正しいメソッド(Inventory.truncate())を呼び出します。

@basic_authは、機密操作(POST / DELETEなど)の認証を提供するデコレータ/ラッパーです。セキュリティが心配な場合は、oAuthデコレーターも利用できます。

最後に、アクションが呼び出されます:

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

魔法のように見えますが、実際には非常に簡単です。最も良い点は、delete()を再利用して、モデルに別のアクションを追加することで、1つまたは複数の結果の削除を処理できることです。


3

すべてのデータストアを削除するには、すべての種類を1つずつ削除します。google appengineダッシュボード。次の手順に従ってください。

  1. https://console.cloud.google.com/datastore/settingsにログインします
  2. [ データストア管理を開く]をクリックします。(有効になっていない場合は有効にします。)
  3. すべてのエンティティを選択してDeleteキーを押します(このステップでは、選択したすべての種類を削除するためにマップ削減ジョブを実行します)。

詳細については、この画像を参照してくださいhttp://storage.googleapis.com/bnifsc/Screenshot%20from%202015-01-31%2023%3A58%3A41.png


2

大量のデータがある場合、Webインターフェースの使用には時間がかかる可能性があります。App Engineのランチャーユーティリティは、チェックボックス「起動時にクリアデータストア」であなた一度で削除すべてのことができます。このユーティリティは、WindowsとMac(Pythonフレームワーク)の両方で使用できるようになりました。


2

開発サーバーの場合、Google App Engineランチャーを介してサーバーを実行する代わりに、ターミナルから次のように実行できます。

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

例:アプリケーション「リーダー」はポート15080で実行されます。コードを変更してサーバーを再起動したら、「dev_appserver.py --port = 15080 --clear_datastore = yes reader」を実行します。

それは私にとって良いことです。



1

多くの場合、すべてのデータストアを削除したくないので、/ war / WEB-INF / local_db.binのクリーンなコピーをソース管理から引き出します。それは私だけかもしれませんが、開発モードが停止していても、プルする前にファイルを物理的に削除する必要があるようです。これは、EclipseのSubversionプラグインを使用しているWindowsの場合です。


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アプリのサンプルを30秒を超えて自動化することを考えています。


これは有効なphpでもありません。import?定数をオブジェクトインスタンスとして定義しますか?
ジョシュJ

0
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)))

1
これでうまくいくとは思いません。AppengineはSorry, unexpected error: The kind "__Stat_Kind__" is reserved.これについて不平を言うappengineには、このメソッドによって公開される可能性のある内部統計エンティティーがあるようです(最後にバグの可能性がありますか?)
消えた

0

ローカルではなく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()

0
  • svpinoの考えを続けると、削除としてマークされたレコードを再利用するのが賢明です。(彼のアイデアは削除することではなく、「削除された」未使用のレコードとしてマークすることでした)。作業コピーを処理し、状態の違いのみ(目的のタスクの前後)をデータストアに書き込むための少しのキャッシュ/ memcacheは、データストアをより良くします。大きなタスクの場合、memcacheが消えた場合のデータ損失を回避するために、データストアに差分差分チャンクを書き込むことが可能です。損失を防ぐために、memcachedの結果の整合性/存在を確認し、タスク(または必要な部分)を再起動して、不足している計算を繰り返すことができます。データの差分がデータストアに書き込まれると、必要な計算がキューで破棄されます。

  • マップの縮小に似た他のアイデアは、エンティティの種類をいくつかの異なるエンティティの種類に分割することです。そのため、エンティティはまとめて収集され、単一のエンティティの種類として最終ユーザーに表示されます。エントリは「削除済み」としてのみマークされます。シャードあたりの「削除された」エントリの量が制限を超えると、「生きた」エントリが他のシャードに分散され、このシャードは永久に閉じられ、開発コンソールから手動で削除されます(少ないコストで)更新:コンソールにドロップテーブルがないようです通常の価格でレコードごとにのみ削除します。

  • 時間の経過時に次の試行を続行できるように、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;
    }
  • また、候補(関連レコード)を別のテーブルに入れる代わりに、プライマリテーブルに追加フィールドを作成すると便利な場合もあります。はい、フィールドは計算コストがほとんどない、インデックス付けされていない/シリアル化された配列である可能性があります。

0

開発サーバーの迅速なソリューションを必要とするすべての人(2016年2月の執筆時点):

  1. 開発サーバーを停止します。
  2. ターゲットを削除するディレクトリをます。
  3. プロジェクトをリビルドします。

これにより、データストアからすべてのデータがワイプされます。


0

ライブデータストアのすべてのデータ削除するための既存のソリューションにとても不満を感じていました、30秒以内にかなりの量のデータを削除できる小さなGAEアプリを作成しました。

etcのインストール方法: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);

開発サーバーでうまく機能します


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.