Google App Engine で Datastore を Python 対話シェルから参照する
いまさらながらに Google App Engine をちょろちょろと触っている。
Datastore を対話シェルから使えると便利そうなので、やり方を確立してみた。
結論としては次のコードを対話シェル上で実行すれば使えるようになった。(Google App Engine SDK for Python Windows 版 1.4.0 にて確認)
import os
import sys
import tempfile
DIR_PATH = r"C:\Program Files\Google\google_appengine"
APP_ID = "helloworld"
sys.path += [
  DIR_PATH,
  os.path.join(DIR_PATH, 'lib', 'antlr3'),
  os.path.join(DIR_PATH, 'lib', 'django'),
  os.path.join(DIR_PATH, 'lib', 'fancy_urllib'),
  os.path.join(DIR_PATH, 'lib', 'ipaddr'),
  os.path.join(DIR_PATH, 'lib', 'webob'),
  os.path.join(DIR_PATH, 'lib', 'yaml', 'lib'),
]
from google.appengine.api import apiproxy_stub_map,datastore_file_stub
os.environ['APPLICATION_ID'] = APP_ID
datastore_path = os.path.join(tempfile.gettempdir(), 'dev_appserver.datastore')
apiproxy_stub_map.apiproxy = apiproxy_stub_map.APIProxyStubMap()
datastore = datastore_file_stub.DatastoreFileStub(APP_ID, datastore_path)
apiproxy_stub_map.apiproxy.RegisterStub('datastore_v3', datastore)
Windows 版以外でも、DIR_PATH のところをインストール先のパスに変更すれば動くと思う。APP_ID は helloworld にしているが、自分のアプリケーションの ID に変えると、ローカルでテスト中のデータを読み取れる。
こんな感じに試せて嬉しい。
>>> from google.appengine.ext import db >>> class A(db.Model): ... t = db.StringProperty() ... >>> a = A() >>> a.t = 'test' >>> a.put() datastore_types.Key.from_path(u'A', 1L, _app=u'helloworld') >>> a.key().id() 1L >>> a.t 'test' >>> A.all().count() 1
Web から使う DB と同じものを参照しているので、Web で設定した内容をインタラクティブ シェル上で確認することもできて嬉しい。
スクリプトを作るまで
何も考えずにスクリプト パスを通して DataStore の API を叩いてみると次の例外が発生した。
google.appengine.api.datastore_errors.BadArgumentError: app must not be empty.
datastore_types.py にて次のようにして APPLICATION_ID を参照していたので、
def ResolveAppId(app):
  """Validate app id, providing a default.
  (snip)
  """
  if app is None:
    app = os.environ.get('APPLICATION_ID', '')
  ValidateString(app, 'app', datastore_errors.BadArgumentError)
  return app
MS-DOS 上で環境変数 APPLICATION_ID を設定してやった。
set APPLICATION_ID=test
すると、次のようなエラーが。
AssertionError: No api proxy found for service "datastore_v3"
このへんで諦めつつ検索したら、Unit testing model classes in Google App Engine に単体テストの手順があったのでソースを奪ってきた。
ここのソースでは DatastoreFileStub に '/dev/null' を渡していて、一時的な DataStore を作成していた。('/dev/null' と聞くと Windows では動かなさそうに見えたが、App Engine SDK で '/dev/null' のときは特別扱いしていたので関係ない)
今回は Web 側のデータを読み込みたかったので、SDK のソースを辿っていたら、tools\dev_appserver_main.py に DataStore として
os.path.join(tempfile.gettempdir(),
             'dev_appserver.datastore'),
が利用されてることが分かったので、この値を利用するようにしてみた。
