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_IDhelloworld にしているが、自分のアプリケーションの 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'),

が利用されてることが分かったので、この値を利用するようにしてみた。